glebtv-rails-uploader 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +241 -0
  3. data/Rakefile +26 -0
  4. data/app/assets/javascripts/uploader/application.js +9 -0
  5. data/app/assets/javascripts/uploader/rails_admin.js +25 -0
  6. data/app/assets/stylesheets/uploader/application.css +7 -0
  7. data/app/controllers/uploader/attachments_controller.rb +67 -0
  8. data/app/views/rails_admin/main/_form_rails_uploader.haml +10 -0
  9. data/app/views/uploader/default/_container.html.erb +67 -0
  10. data/app/views/uploader/default/_download.html.erb +17 -0
  11. data/app/views/uploader/default/_upload.html.erb +14 -0
  12. data/config/locales/en.yml +5 -0
  13. data/config/locales/ru.yml +5 -0
  14. data/config/locales/uk.yml +5 -0
  15. data/config/routes.rb +7 -0
  16. data/lib/file_size_validator.rb +66 -0
  17. data/lib/glebtv-rails-uploader.rb +3 -0
  18. data/lib/uploader.rb +35 -0
  19. data/lib/uploader/asset.rb +47 -0
  20. data/lib/uploader/engine.rb +25 -0
  21. data/lib/uploader/fileuploads.rb +109 -0
  22. data/lib/uploader/helpers/field_tag.rb +100 -0
  23. data/lib/uploader/helpers/form_builder.rb +16 -0
  24. data/lib/uploader/helpers/form_tag_helper.rb +16 -0
  25. data/lib/uploader/hooks/active_record.rb +5 -0
  26. data/lib/uploader/hooks/formtastic.rb +14 -0
  27. data/lib/uploader/hooks/simple_form.rb +9 -0
  28. data/lib/uploader/rails_admin/field.rb +28 -0
  29. data/lib/uploader/version.rb +3 -0
  30. data/spec/dummy/README.rdoc +261 -0
  31. data/spec/dummy/Rakefile +7 -0
  32. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  33. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  34. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  35. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  36. data/spec/dummy/app/models/article.rb +7 -0
  37. data/spec/dummy/app/models/asset.rb +27 -0
  38. data/spec/dummy/app/models/picture.rb +5 -0
  39. data/spec/dummy/app/uploaders/picture_uploader.rb +55 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  41. data/spec/dummy/config.ru +4 -0
  42. data/spec/dummy/config/application.rb +58 -0
  43. data/spec/dummy/config/boot.rb +10 -0
  44. data/spec/dummy/config/database.yml +25 -0
  45. data/spec/dummy/config/environment.rb +5 -0
  46. data/spec/dummy/config/environments/development.rb +37 -0
  47. data/spec/dummy/config/environments/production.rb +67 -0
  48. data/spec/dummy/config/environments/test.rb +37 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/inflections.rb +15 -0
  51. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  52. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  53. data/spec/dummy/config/initializers/session_store.rb +8 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +5 -0
  56. data/spec/dummy/config/routes.rb +3 -0
  57. data/spec/dummy/db/migrate/20120508093416_create_assets.rb +19 -0
  58. data/spec/dummy/db/migrate/20120508093830_create_articles.rb +10 -0
  59. data/spec/dummy/public/404.html +26 -0
  60. data/spec/dummy/public/422.html +26 -0
  61. data/spec/dummy/public/500.html +25 -0
  62. data/spec/dummy/public/favicon.ico +0 -0
  63. data/spec/dummy/script/rails +6 -0
  64. data/spec/factories/articles.rb +8 -0
  65. data/spec/factories/assets.rb +11 -0
  66. data/spec/factories/files/rails.png +0 -0
  67. data/spec/fileuploads_spec.rb +57 -0
  68. data/spec/requests/attachments_controller_spec.rb +38 -0
  69. data/spec/spec_helper.rb +52 -0
  70. data/spec/uploader_spec.rb +18 -0
  71. data/vendor/assets/images/uploader/but_del_tag2.png +0 -0
  72. data/vendor/assets/images/uploader/ico_attach.png +0 -0
  73. data/vendor/assets/images/uploader/preloader.gif +0 -0
  74. data/vendor/assets/images/uploader/progressBarFillBg.png +0 -0
  75. data/vendor/assets/javascripts/uploader/jquery.fileupload-ip.js +160 -0
  76. data/vendor/assets/javascripts/uploader/jquery.fileupload-ui.js +637 -0
  77. data/vendor/assets/javascripts/uploader/jquery.fileupload.js +904 -0
  78. data/vendor/assets/javascripts/uploader/jquery.iframe-transport.js +171 -0
  79. data/vendor/assets/javascripts/uploader/jquery.ui.widget.js +282 -0
  80. data/vendor/assets/javascripts/uploader/load-image.min.js +1 -0
  81. data/vendor/assets/javascripts/uploader/locales/en.js +27 -0
  82. data/vendor/assets/javascripts/uploader/locales/ru.js +27 -0
  83. data/vendor/assets/javascripts/uploader/locales/uk.js +27 -0
  84. data/vendor/assets/javascripts/uploader/tmpl.min.js +1 -0
  85. data/vendor/assets/stylesheets/uploader/default.css +214 -0
  86. data/vendor/assets/stylesheets/uploader/jquery.fileupload-ui.css +30 -0
  87. metadata +317 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Fodojo http://fodojo.com/
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # this fork adds mongoid support
2
+
3
+ This fork works when both simple form and formtastic are loaded
4
+
5
+ Also nested associations seem to be working
6
+
7
+ a little howto for mongoid / carrierwave:
8
+
9
+ ### Asset Parent Model (common)
10
+ ``` ruby
11
+ # models/asset.rb
12
+ class Asset
13
+ include Mongoid::Document
14
+ include Uploader::Asset
15
+
16
+ field :guid, type: String
17
+ belongs_to :assetable, polymorphic: true
18
+ end
19
+ ```
20
+
21
+ ### Your asset model
22
+ ``` ruby
23
+ # models/cover.rb
24
+ class Cover < Asset
25
+ # DO NOT add this!
26
+ # belongs_to :post
27
+
28
+ # field name must be 'data'
29
+ mount_uploader :data, CoverUploader
30
+
31
+ validates :data,
32
+ :presence => true,
33
+ :file_size => {
34
+ :maximum => 5.megabytes.to_i
35
+ }
36
+
37
+ def to_jq_upload
38
+ [{
39
+ 'id' => id.to_s,
40
+ "filename" => File.basename(data.path),
41
+ "url" => data.url,
42
+ 'thumb_url' => data.thumb.url,
43
+ }]
44
+ end
45
+ end
46
+ ```
47
+
48
+ ### Model to which you want to add assets
49
+ ```ruby
50
+ # models/post.rb
51
+ class Post
52
+ include Mongoid::Document
53
+ include Uploader::Fileuploads
54
+ has_one :cover, as: :assetable
55
+ fileuploads :cover
56
+ end
57
+ ```
58
+
59
+ ### has_many
60
+
61
+ ```ruby
62
+ class Album
63
+ # optional built-in sorting for rails_admin
64
+ def sort_assets!(order)
65
+ pos = 0
66
+ order.each do |pic_id|
67
+ pic = self.pictures.find(pic_id)
68
+ pic.sort = (pos+=1)
69
+ pic.save!
70
+ end
71
+ end
72
+
73
+ has_many :pictures, as: :assetable, dependent: :destroy
74
+ fileuploads :pictures
75
+
76
+ accepts_nested_attributes_for :pictures
77
+
78
+ rails_admin do
79
+ edit do
80
+ ...
81
+ field :pictures, :rails_uploader
82
+ end
83
+ end
84
+ end
85
+
86
+ ```
87
+
88
+ ### CarrierWave uploader - all like usual
89
+ ```ruby
90
+ # uploades/cover_uploader.rb
91
+ class CoverUploader < CarrierWave::Uploader::Base
92
+ include CarrierWave::MiniMagick
93
+
94
+ storage :file
95
+
96
+ def store_dir
97
+ "uploads/covers/#{model.id}"
98
+ end
99
+
100
+ version :thumb do
101
+ process resize_to_limit: [50, 50]
102
+ end
103
+ end
104
+ ```
105
+
106
+ # Active Admin and RailsAdmin are both working
107
+
108
+ # RailsAdmin Integration
109
+ ``` ruby
110
+ rails_admin do
111
+ edit do
112
+ ...
113
+ field :pictures, :rails_uploader
114
+ end
115
+ end
116
+ ```
117
+
118
+ # HTML5 File uploader for rails
119
+
120
+ This gem use https://github.com/blueimp/jQuery-File-Upload for upload files.
121
+
122
+ Preview:
123
+
124
+ ![Uploader in use](http://img39.imageshack.us/img39/2206/railsuploader.png)
125
+
126
+ ## Install
127
+
128
+ In Gemfile:
129
+
130
+ gem "glebtv-rails-uploader", require: 'rails-uploader'
131
+
132
+ In routes:
133
+
134
+ ``` ruby
135
+ mount Uploader::Engine => '/uploader'
136
+ ```
137
+
138
+ ## Usage
139
+
140
+ Architecture to store uploaded files (cancan integration):
141
+
142
+ ``` ruby
143
+ class Asset < ActiveRecord::Base
144
+ include Uploader::Asset
145
+
146
+ def uploader_create(params, request = nil)
147
+ ability = Ability.new(request.env['warden'].user)
148
+
149
+ if ability.can? :create, self
150
+ self.user = request.env['warden'].user
151
+ super
152
+ else
153
+ errors.add(:id, :access_denied)
154
+ end
155
+ end
156
+
157
+ def uploader_destroy(params, request = nil)
158
+ ability = Ability.new(request.env['warden'].user)
159
+
160
+ if ability.can? :delete, self
161
+ super
162
+ else
163
+ errors.add(:id, :access_denied)
164
+ end
165
+ end
166
+ end
167
+
168
+ class Picture < Asset
169
+ mount_uploader :data, PictureUploader
170
+
171
+ validates_integrity_of :data
172
+ validates_filesize_of :data, :maximum => 2.megabytes.to_i
173
+ end
174
+ ```
175
+
176
+ For example user has one picture:
177
+
178
+ ``` ruby
179
+ class User < ActiveRecord::Base
180
+ has_one :picture, :as => :assetable, :dependent => :destroy
181
+
182
+ fileuploads :picture
183
+
184
+ # If your don't use strong_parameters, uncomment next line
185
+ # attr_accessible :fileupload_guid
186
+ end
187
+ ```
188
+
189
+ Find asset by foreign key or guid:
190
+
191
+ ``` ruby
192
+ @user.fileupload_asset(:picture)
193
+ ```
194
+
195
+ ### Include assets
196
+
197
+ Javascripts:
198
+
199
+ ``` ruby
200
+ //= require uploader/application
201
+ ```
202
+
203
+ Stylesheets:
204
+
205
+ ``` ruby
206
+ *= require uploader/application
207
+ ```
208
+
209
+ ### Views
210
+
211
+ ``` ruby
212
+ <%= uploader_field_tag :article, :photo %>
213
+ ```
214
+
215
+ or FormBuilder:
216
+
217
+ ``` ruby
218
+ <%= form.uploader_field :photo %>
219
+ ```
220
+
221
+ ### Formtastic
222
+
223
+ ``` ruby
224
+ <%= f.input :picture, :as => :uploader %>
225
+ ```
226
+
227
+ ### SimpleForm
228
+
229
+ ``` ruby
230
+ <%= f.input :picture, :as => :uploader %>
231
+ ```
232
+
233
+ ## Contributing
234
+
235
+ 1. Fork it
236
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
237
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
238
+ 4. Push to the branch (`git push origin my-new-feature`)
239
+ 5. Create new Pull Request
240
+
241
+ Copyright (c) 2013 Fodojo, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'rdoc/task'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :test
10
+
11
+ desc 'Test the rails-uploader plugin.'
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib'
14
+ t.libs << 'test'
15
+ t.pattern = 'test/**/*_test.rb'
16
+ t.verbose = true
17
+ end
18
+
19
+ desc 'Generate documentation for the rails-uploader plugin.'
20
+ Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'Rails Uploader'
23
+ rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.rdoc_files.include('README.rdoc')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
@@ -0,0 +1,9 @@
1
+ //= require uploader/locales/en
2
+ //= require uploader/tmpl.min
3
+ //= require uploader/load-image.min
4
+ //= require uploader/jquery.ui.widget
5
+ //= require uploader/jquery.iframe-transport
6
+ //= require uploader/jquery.fileupload
7
+ //= require uploader/jquery.fileupload-ui
8
+
9
+
@@ -0,0 +1,25 @@
1
+ //= require uploader/locales/en
2
+ //= require uploader/tmpl.min
3
+ //= require uploader/load-image.min
4
+ //= require uploader/jquery.iframe-transport
5
+ //= require uploader/jquery.fileupload
6
+ //= require uploader/jquery.fileupload-ui
7
+
8
+ $('.uploader-dnd-area input[type=file]').trigger("init.uploader");
9
+
10
+ $('.uploader-files').each(function() {
11
+ var $t = $(this);
12
+ $t.sortable({
13
+ update: function(event, ui) {
14
+ var sort = [];
15
+ $t.children().each(function() {
16
+ sort.push($(this).data('id'));
17
+ });
18
+ $.ajax({
19
+ type: 'POST',
20
+ url: $t.data('sortPath'),
21
+ data: {sort: sort.join('|')}
22
+ })
23
+ }
24
+ })
25
+ });
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require uploader/jquery.fileupload-ui
6
+ *= require uploader/default
7
+ */
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+ module Uploader
3
+ class AttachmentsController < ActionController::Metal
4
+ include AbstractController::Callbacks
5
+
6
+ before_filter :find_klass
7
+
8
+ def create
9
+ @asset = @klass.new(params[:asset])
10
+ @asset.uploader_create(params, request)
11
+ render_resourse(@asset, 201)
12
+ end
13
+
14
+ def destroy
15
+ @asset = @klass.find(params[:id])
16
+ @asset.uploader_destroy(params, request)
17
+ render_resourse(@asset, 200)
18
+ end
19
+
20
+ def sort
21
+ @model = params[:assetable_type].safe_constantize
22
+ @object = @model.find(params[:assetable_id])
23
+
24
+ if @object.respond_to?(:sort_assets!)
25
+ @object.sort_assets!(params[:sort].split('|'))
26
+ end
27
+
28
+ self.status = 200
29
+ self.content_type = "application/json"
30
+ self.response_body = '{"ok": true}'
31
+ end
32
+
33
+ protected
34
+
35
+
36
+ def airbrake_request_data
37
+ {
38
+ :controller => params[:controller],
39
+ :action => params[:action],
40
+ }
41
+ end
42
+
43
+ def find_klass
44
+ @klass = params[:klass].blank? ? nil : params[:klass].safe_constantize
45
+ raise ActionController::RoutingError.new("Class not found #{params[:klass]}") if @klass.nil?
46
+ end
47
+
48
+ def render_resourse(record, status = 200)
49
+ if record.errors.empty?
50
+ if record.respond_to?(:to_jq_upload)
51
+ render_json(record.to_jq_upload.to_json(:root => false), status)
52
+ else
53
+ render_json([record].to_json(:root => false), status)
54
+ end
55
+
56
+ else
57
+ render_json([record.errors].to_json, 422)
58
+ end
59
+ end
60
+
61
+ def render_json(body, status = 200)
62
+ self.status = status
63
+ self.content_type = "application/json"
64
+ self.response_body = body
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ = stylesheet_link_tag "uploader/application.css"
2
+ = form.send 'uploader_field', field.method_name, field.html_attributes
3
+ :javascript
4
+ (function(d, s, id) {
5
+ var js, fjs = d.getElementsByTagName(s)[0];
6
+ if (d.getElementById(id)) return;
7
+ js = d.createElement(s); js.id = id;
8
+ js.src = "/assets/uploader/rails_admin.js";
9
+ fjs.parentNode.appendChild(js);
10
+ }(document, 'script', 'uploader-jssdk'));
@@ -0,0 +1,67 @@
1
+ <% if field.object_name =~ /.*\[.*\]\[(.*)\]/ %>
2
+ <% assoc = true %>
3
+ <% field.object.fileupload_guid = field.object.fileupload_guid + '_' + $1 %>
4
+ <% else %>
5
+ <% assoc = false %>
6
+ <% end %>
7
+
8
+ <%= content_tag(:div, :id => field.id, :class => "uploader-dnd-area") do -%>
9
+ <% # if assoc || field.object.new_record? %>
10
+ <%= hidden_field(field.object_name, :fileupload_guid, :object => field.object) %>
11
+ <% # end %>
12
+
13
+ <div class="uploader-files" data-sort-path="<%= field.sort_path %>"></div>
14
+
15
+ <div class="uploader-dnd-hints">
16
+ <div class="uploader-button gray fileinput-button">
17
+ <div><%= I18n.t('uploader.button') %></div>
18
+ <%= fields_for field.object do |f| -%>
19
+ <%= f.fields_for field.method_name, field.klass.new do |m| -%>
20
+ <%= m.file_field(:data, field.input_html) %>
21
+ <% end -%>
22
+ <% end -%>
23
+ </div>
24
+
25
+ <div class="uploader-dnd-hint">
26
+ <%= I18n.t('uploader.or') %>
27
+ <span><%= I18n.t('uploader.drop') %></span>
28
+ </div>
29
+ </div>
30
+
31
+ <%= render :partial => "uploader/#{field.theme}/upload", :locals => {:field => field} %>
32
+ <%= render :partial => "uploader/#{field.theme}/download", :locals => {:field => field} %>
33
+
34
+ <script type="text/javascript">
35
+ $(function () {
36
+ var container = $("#<%= field.id %> div.uploader-files");
37
+
38
+ $('#<%= field.id %> input[type="file"]').attr('name', 'uploader_field').bind("init.uploader", function (e) {
39
+ if (!$.fn.fileupload) {
40
+ // not yet loaded
41
+ return false;
42
+ }
43
+
44
+ $(this).fileupload({
45
+ dataType: 'json',
46
+ dropZone: $("#<%= field.id %>"),
47
+ autoUpload: true,
48
+ paramName: "asset[data]",
49
+ formData: function (form) {
50
+ return [];
51
+ },
52
+ filesContainer: container,
53
+ namespace: 'uploader',
54
+ uploadTemplateId: 'template-upload-<%= field.klass %>',
55
+ downloadTemplateId: 'template-download-<%= field.klass %>'
56
+ });
57
+
58
+ <% if field.exists? -%>
59
+ <% fv = field.values.map { |v| v.respond_to?(:to_jq_upload) ? v.to_jq_upload.first : v } %>
60
+ $(this).data("fileupload")
61
+ ._renderDownload(<%=raw fv.to_json(:root => false) %>)
62
+ .appendTo(container);
63
+ <% end -%>
64
+ }).trigger("init.uploader");
65
+ });
66
+ </script>
67
+ <% end -%>