rails_admin_uploader 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +78 -0
  6. data/Rakefile +1 -0
  7. data/app/assets/images/rails_admin_uploader/loading.gif +0 -0
  8. data/app/assets/images/rails_admin_uploader/progressbar.gif +0 -0
  9. data/app/assets/javascripts/rails_admin_uploader.coffee +261 -0
  10. data/app/assets/javascripts/rails_admin_uploader/canvas-to-blob.js +95 -0
  11. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-audio.js +112 -0
  12. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-image.js +321 -0
  13. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-process.js +175 -0
  14. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-ui.js +710 -0
  15. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-validate.js +122 -0
  16. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-video.js +112 -0
  17. data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload.js +1477 -0
  18. data/app/assets/javascripts/rails_admin_uploader/jquery.iframe-transport.js +217 -0
  19. data/app/assets/javascripts/rails_admin_uploader/load-image.all.min.js +1 -0
  20. data/app/assets/javascripts/rails_admin_uploader/tmpl.js +87 -0
  21. data/app/assets/stylesheets/rails_admin_uploader.sass +2 -0
  22. data/app/assets/stylesheets/rails_admin_uploader/jquery.fileupload-ui.scss +57 -0
  23. data/app/assets/stylesheets/rails_admin_uploader/jquery.fileupload.scss +37 -0
  24. data/app/controllers/rails_admin_uploader/attachments_controller.rb +94 -0
  25. data/app/views/rails_admin/main/_rails_admin_uploader.html.haml +16 -0
  26. data/bin/console +14 -0
  27. data/bin/setup +7 -0
  28. data/config/locales/ru.yml +6 -0
  29. data/config/routes.rb +8 -0
  30. data/lib/rails_admin_uploader.rb +15 -0
  31. data/lib/rails_admin_uploader/asset.rb +19 -0
  32. data/lib/rails_admin_uploader/base.rb +50 -0
  33. data/lib/rails_admin_uploader/engine.rb +6 -0
  34. data/lib/rails_admin_uploader/field.rb +12 -0
  35. data/lib/rails_admin_uploader/version.rb +3 -0
  36. data/rails_admin_uploader.gemspec +24 -0
  37. metadata +107 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fdc91b58e311a7ff0e82b52fade2fb14ebf6d885
4
+ data.tar.gz: 5f14d3f71459413afb96a773ed01b99911d1a3fa
5
+ SHA512:
6
+ metadata.gz: 3a23bb89acbb9557bf99aacd9563798bddc30ce62adade4d027575c3ff165652c8a7042249c954ed9ffda54591c23e11d4f4844db6bbf06d680c6358652d0d24
7
+ data.tar.gz: 818c8e433a60b716a25e4fe344dc460f46de4b63e316c6c7b44a45f01d0c336351217d94189c8b5385cfbc65a66b2b98d33f93450611cf40c8aa03b3b68f5db4
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rails_admin_uploader.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 glebtv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,78 @@
1
+ # RailsAdminUploader
2
+
3
+ Mass file uploads via [jQuery-File-Upload](https://github.com/blueimp/jQuery-File-Upload) for Rails Admin
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'rails_admin_uploader'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install rails_admin_uploader
20
+
21
+ Mount the gem's engine. Add to ```config/routes.rb```:
22
+
23
+ mount RailsAdminUploader::Engine => '/ra_uploader', as: 'rails_admin_uploader'
24
+
25
+ Add this line to ```app/assets/javascripts/rails_admin/custom/ui.coffee```
26
+
27
+ #= require rails_admin_uploader
28
+
29
+ Create this file if it doesn't exist in your project.
30
+
31
+
32
+ Add this line to ```app/assets/stylesheets/rails_admin/custom/theming.sass```
33
+
34
+ @import rails_admin_uploader
35
+
36
+ Create this file if it doesn't exist in your project.
37
+
38
+ ## Usage
39
+
40
+ Configure your models:
41
+
42
+ class Obj
43
+ has_many :images
44
+ has_many :plans
45
+ include RailsAdminUploader::Base
46
+ rails_admin_uploader :images, :plans
47
+ # add a string field :ra_token to DB (required)
48
+ rails_admin do
49
+ edit do
50
+ field :image, :rails_admin_uploader
51
+ field :plans, :rails_admin_uploader
52
+ end
53
+ end
54
+ end
55
+ class Image
56
+ belongs_to :obj
57
+ include RailsAdminUploader::Asset
58
+
59
+ # add a string field :ra_token to DB (required)
60
+ # add an image field :image to DB (required)
61
+ # add an integer field :sort to DB (optional)
62
+ # add a boolean field :enabled to DB (optional)
63
+ end
64
+
65
+ Set up CanCan (required)
66
+
67
+ ## Contributing
68
+
69
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/rs-pro/rails_admin_uploader).
70
+
71
+ ## License
72
+
73
+ Somewhat based on [rails-uploader](https://github.com/superp/rails-uploader)
74
+ Copyright (c) 2013 Fodojo, released under the MIT license
75
+
76
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
77
+ Copyright (c) 2015 glebtv, released under the MIT license
78
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,261 @@
1
+ #= require rails_admin_uploader/tmpl
2
+ #= require rails_admin_uploader/canvas-to-blob
3
+ #= require rails_admin_uploader/load-image.all.min.js
4
+ #= require rails_admin_uploader/jquery.fileupload
5
+ #= require rails_admin_uploader/jquery.fileupload-process
6
+ #= require rails_admin_uploader/jquery.fileupload-image
7
+ #= require rails_admin_uploader/jquery.fileupload-audio
8
+ #= require rails_admin_uploader/jquery.fileupload-video
9
+ #= require rails_admin_uploader/jquery.fileupload-validate
10
+ #= require rails_admin_uploader/jquery.iframe-transport
11
+ #= require rails_admin_uploader/jquery.fileupload-ui
12
+
13
+ upload_template = """
14
+ <script id="ra_uploader_upload" type="text/x-tmpl">
15
+ {% for (var i=0, file; file=o.files[i]; i++) { %}
16
+ <tr class="template-upload">
17
+ {% if (o.options.flags.sortable) { %}
18
+ <td></td>
19
+ {% } %}
20
+ {% if (o.options.flags.enableable) { %}
21
+ <td></td>
22
+ {% } %}
23
+ <td width="200">
24
+ <span class="preview"></span>
25
+ </td>
26
+ <td width="200">
27
+ <div class="fileName">{%=file.name%}</div>
28
+ <div class="fileError"><strong class="error text-danger"></strong></div>
29
+ <div class="fileWeight">{%=o.formatFileSize(file.size)%}</div>
30
+ </td>
31
+ <td>
32
+ <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
33
+ </td>
34
+ <td>
35
+ <button class="btn btn-warning btn-sm cancel">
36
+ <i class="fa fa-ban"></i>
37
+ </button>
38
+ </td>
39
+ </tr>
40
+ {% } %}
41
+ </script>
42
+
43
+ """
44
+
45
+ e_spin = '<a class="label label-primary">
46
+ <i class="fa fa-spinner fa-spin"></i>
47
+ </a>'
48
+ e_on = '<a class="label label-success">
49
+ <i class="fa fa-check"></i>
50
+ </a>'
51
+ e_off = '<a class="label label-danger">
52
+ <i class="fa fa-times"></i>
53
+ </a>'
54
+
55
+ download_template = """
56
+ <script id="ra_uploader_download" type="text/x-tmpl">
57
+ {% for (var i=0, file; file=o.files[i]; i++) { %}
58
+ <tr data-id="{%=file.id%}" class="template-download">
59
+ {% if (o.options.flags.sortable) { %}
60
+ <td class="sort-handle">
61
+ <i class="fa fa-sort"></i>
62
+ </td>
63
+ {% } %}
64
+ {%= JSON.stringify(o) %}
65
+ {% if (o.options.flags.enableable) { %}
66
+ <td class="enable-button">
67
+ {% if (file.enabled) { %}
68
+ #{e_on}
69
+ {% } else { %}
70
+ #{e_off}
71
+ {% } %}
72
+ </td>
73
+ {% } %}
74
+ <td width="200">
75
+ <a target="_blank" href="{%=file.url%}">
76
+ <img src="{%=file.thumb_url%}" title="{%=file.filename%}" />
77
+ </a>
78
+ </td>
79
+ <td width="200">
80
+ <div class="fileName">
81
+ <a target="_blank" href="{%=file.url%}">{%=file.filename%}</a>
82
+ </div>
83
+ <div class="fileWeight">{%=o.formatFileSize(file.size)%}</div>
84
+ {% if (file.error) { %}
85
+ <div><span class="label label-danger">Ошибка</span> {%=file.error%}</div>
86
+ {% } %}
87
+ </td>
88
+ <td>
89
+ {% if (o.options.flags.nameable) { %}
90
+ <input class="nameable" value="{%=file.name%}" placeholder="Название"/>
91
+ <i class="spinner fa fa-spinner fa-spin" style="display: none;"></i>
92
+ {% } %}
93
+ <td>
94
+ <a class="btn btn-danger btn-sm delete">
95
+ <i class="fa fa-trash-o"></i>
96
+ </a>
97
+ </td>
98
+ </div>
99
+ {% } %}
100
+ </script>
101
+
102
+ """
103
+
104
+ class RaUploader
105
+ constructor: ($t)->
106
+ @$t = $t
107
+
108
+ @url = @$t.data('url')
109
+ @klass = @$t.data('klass')
110
+ @id = @$t.data('id')
111
+ @field = @$t.data('field')
112
+ @$f = @$t.find('.files')
113
+ @flags = @$t.data('flags')
114
+
115
+ @guid = @$t.find('input[type=hidden]').val()
116
+
117
+ @$t.disableSelection()
118
+
119
+ @initUploader()
120
+ @loadFiles()
121
+
122
+ data: =>
123
+ r = {
124
+ field: @field
125
+ klass: @klass
126
+ guid: @guid
127
+ }
128
+ if @id
129
+ r.obj_id = @id
130
+ r
131
+
132
+ initSortable: ->
133
+ return false unless @flags.sortable
134
+ @$t.find('.files tbody').sortable
135
+ placeholder: 'attach_item'
136
+ cursor: 'move'
137
+ handle: ".sort-handle",
138
+ update: (event, ui) =>
139
+ order = []
140
+ @$t.find('.template-download').each ->
141
+ $i = $(this)
142
+ order.push($i.data('id'))
143
+ d = @data()
144
+ d.order = order
145
+ $.ajax
146
+ url: @url
147
+ type: 'POST'
148
+ dataType: 'json'
149
+ data: d
150
+ error: (r)->
151
+ alert(r)
152
+
153
+ initEnableable: =>
154
+ return false unless @flags.enableable
155
+ t = @
156
+ @$t.on('click', '.enable-button a', (e)->
157
+ $t = $(this)
158
+ $i = $t.parents('.template-download')
159
+ e.preventDefault()
160
+ d = t.data()
161
+ d.img = {enabled: !$t.hasClass('label-success')}
162
+ $p = $t.parent()
163
+ $p.html(e_spin)
164
+ id = $i.data('id')
165
+ $.ajax
166
+ url: "#{t.url}/#{id}"
167
+ type: 'PUT'
168
+ dataType: 'json'
169
+ data: d
170
+ success: (r)->
171
+ $p.html(if r.enabled then e_on else e_off)
172
+ error: (r)->
173
+ alert(r)
174
+ )
175
+
176
+ initNameable: =>
177
+ return false unless @flags.nameable
178
+ t = @
179
+ @$t.on('blur', 'input.nameable', (e)->
180
+ $t = $(this)
181
+ $i = $t.parents('.template-download')
182
+ e.preventDefault()
183
+ d = t.data()
184
+ d.img = {name: $t.val()}
185
+ id = $i.data('id')
186
+ $t.next('.spinner').show()
187
+ $.ajax
188
+ url: "#{t.url}/#{id}"
189
+ type: 'PUT'
190
+ dataType: 'json'
191
+ data: d
192
+ success: (r)->
193
+ $t.next('.spinner').hide()
194
+ error: (r)->
195
+ alert(r)
196
+ )
197
+
198
+ initUploader: =>
199
+ t = @
200
+ @$fo = @$t.find('input.fileupload').fileupload(
201
+ url: @url
202
+ dataType: 'json'
203
+ autoUpload: true
204
+ previewMaxWidth: 100
205
+ previewMaxHeight: 100
206
+ formData: (form)=>
207
+ formData = []
208
+ $.each @data(), (name, value) ->
209
+ formData.push
210
+ name: name
211
+ value: value
212
+ formData
213
+ uploadTemplateId: "ra_uploader_upload",
214
+ downloadTemplateId: "ra_uploader_download"
215
+ dropZone: @$t
216
+ filesContainer: @$f
217
+ previewCrop: true
218
+ flags: @flags
219
+ destroy: (e, data) ->
220
+ $i = data.context
221
+ d = t.data()
222
+ id = $i.data('id')
223
+ if confirm("Точно удалить?")
224
+ $.ajax
225
+ url: "#{t.url}/#{id}"
226
+ type: 'DELETE'
227
+ dataType: 'json'
228
+ data: d
229
+ success: (r)->
230
+ $i.remove()
231
+ error: (r)->
232
+ alert(r)
233
+ )
234
+ @uploader = @$fo.data('blueimpFileupload')
235
+
236
+ loadFiles: ->
237
+ $.ajax
238
+ type: 'GET'
239
+ dataType: 'json'
240
+ url: @url
241
+ data: @data()
242
+ success: (r)=>
243
+ @$f.html("")
244
+ @uploader._renderDownload(r.files).appendTo(@$f)
245
+ @initSortable()
246
+ @initEnableable()
247
+ @initNameable()
248
+ error: ->
249
+ @$f.html("Ошибка загрузки списка файлов...").css(color: 'red')
250
+
251
+ init = ->
252
+ $('.fileupload-block').each ->
253
+ new RaUploader($(this))
254
+
255
+
256
+ $(document).on 'pjax:complete', init
257
+ $ ->
258
+ $('body').append(upload_template)
259
+ $('body').append(download_template)
260
+ init()
261
+
@@ -0,0 +1,95 @@
1
+ /*
2
+ * JavaScript Canvas to Blob 2.0.5
3
+ * https://github.com/blueimp/JavaScript-Canvas-to-Blob
4
+ *
5
+ * Copyright 2012, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ *
11
+ * Based on stackoverflow user Stoive's code snippet:
12
+ * http://stackoverflow.com/q/4998908
13
+ */
14
+
15
+ /*jslint nomen: true, regexp: true */
16
+ /*global window, atob, Blob, ArrayBuffer, Uint8Array, define */
17
+
18
+ (function (window) {
19
+ 'use strict';
20
+ var CanvasPrototype = window.HTMLCanvasElement &&
21
+ window.HTMLCanvasElement.prototype,
22
+ hasBlobConstructor = window.Blob && (function () {
23
+ try {
24
+ return Boolean(new Blob());
25
+ } catch (e) {
26
+ return false;
27
+ }
28
+ }()),
29
+ hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
30
+ (function () {
31
+ try {
32
+ return new Blob([new Uint8Array(100)]).size === 100;
33
+ } catch (e) {
34
+ return false;
35
+ }
36
+ }()),
37
+ BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
38
+ window.MozBlobBuilder || window.MSBlobBuilder,
39
+ dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
40
+ window.ArrayBuffer && window.Uint8Array && function (dataURI) {
41
+ var byteString,
42
+ arrayBuffer,
43
+ intArray,
44
+ i,
45
+ mimeString,
46
+ bb;
47
+ if (dataURI.split(',')[0].indexOf('base64') >= 0) {
48
+ // Convert base64 to raw binary data held in a string:
49
+ byteString = atob(dataURI.split(',')[1]);
50
+ } else {
51
+ // Convert base64/URLEncoded data component to raw binary data:
52
+ byteString = decodeURIComponent(dataURI.split(',')[1]);
53
+ }
54
+ // Write the bytes of the string to an ArrayBuffer:
55
+ arrayBuffer = new ArrayBuffer(byteString.length);
56
+ intArray = new Uint8Array(arrayBuffer);
57
+ for (i = 0; i < byteString.length; i += 1) {
58
+ intArray[i] = byteString.charCodeAt(i);
59
+ }
60
+ // Separate out the mime component:
61
+ mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
62
+ // Write the ArrayBuffer (or ArrayBufferView) to a blob:
63
+ if (hasBlobConstructor) {
64
+ return new Blob(
65
+ [hasArrayBufferViewSupport ? intArray : arrayBuffer],
66
+ {type: mimeString}
67
+ );
68
+ }
69
+ bb = new BlobBuilder();
70
+ bb.append(arrayBuffer);
71
+ return bb.getBlob(mimeString);
72
+ };
73
+ if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
74
+ if (CanvasPrototype.mozGetAsFile) {
75
+ CanvasPrototype.toBlob = function (callback, type, quality) {
76
+ if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {
77
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
78
+ } else {
79
+ callback(this.mozGetAsFile('blob', type));
80
+ }
81
+ };
82
+ } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
83
+ CanvasPrototype.toBlob = function (callback, type, quality) {
84
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
85
+ };
86
+ }
87
+ }
88
+ if (typeof define === 'function' && define.amd) {
89
+ define(function () {
90
+ return dataURLtoBlob;
91
+ });
92
+ } else {
93
+ window.dataURLtoBlob = dataURLtoBlob;
94
+ }
95
+ }(window));