attachment_magick 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.gitignore +12 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +159 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.rdoc +98 -0
  6. data/Rakefile +13 -0
  7. data/app/controllers/attachment_magick/images_controller.rb +50 -0
  8. data/app/helpers/attachment_magick/attachment_magick_helper.rb +57 -0
  9. data/app/models/attachment_magick/active_record_image.rb +18 -0
  10. data/app/models/attachment_magick/mongoid_image.rb +29 -0
  11. data/app/views/layouts/attachment_magick/images/_add_image.html.erb +18 -0
  12. data/app/views/layouts/attachment_magick/images/_video_upload.html.erb +2 -0
  13. data/attachment_magick.gemspec +25 -0
  14. data/lib/attachment_magick/configuration/configuration.rb +28 -0
  15. data/lib/attachment_magick/configuration/custom_style.rb +19 -0
  16. data/lib/attachment_magick/dragonfly/init.rb +20 -0
  17. data/lib/attachment_magick/dsl.rb +37 -0
  18. data/lib/attachment_magick/railtie.rb +10 -0
  19. data/lib/attachment_magick/test/attachment_magick_test_helper.rb +43 -0
  20. data/lib/attachment_magick/version.rb +3 -0
  21. data/lib/attachment_magick.rb +78 -0
  22. data/lib/generators/attachment_magick/install_generator.rb +15 -0
  23. data/lib/generators/attachment_magick/migration_generator.rb +17 -0
  24. data/lib/generators/attachment_magick/templates/attachment_magick_migration.rb +18 -0
  25. data/lib/generators/attachment_magick/templates/public/javascripts/swfupload/handlers.js +384 -0
  26. data/lib/generators/attachment_magick/templates/public/javascripts/swfupload/swfupload.js +1132 -0
  27. data/lib/generators/attachment_magick/templates/public/javascripts/swfupload/swfupload.swf +0 -0
  28. data/lib/generators/attachment_magick/templates/public/stylesheets/attachment_magick.css +10 -0
  29. data/lib/generators/attachment_magick/templates/public/stylesheets/swfupload.css +108 -0
  30. data/test/attachment_magick/controllers/images_controller_test.rb +67 -0
  31. data/test/attachment_magick/generators/install_generator_test.rb +34 -0
  32. data/test/attachment_magick/generators/migration_generator_test.rb +16 -0
  33. data/test/attachment_magick/helpers/attachment_magick_test.rb +56 -0
  34. data/test/attachment_magick/units/artist_test.rb +11 -0
  35. data/test/attachment_magick/units/attachment_magick_test.rb +105 -0
  36. data/test/attachment_magick/units/image_test.rb +26 -0
  37. data/test/attachment_magick/units/place_test.rb +8 -0
  38. data/test/dummy/Rakefile +7 -0
  39. data/test/dummy/app/controllers/application_controller.rb +4 -0
  40. data/test/dummy/app/controllers/artists_controller.rb +34 -0
  41. data/test/dummy/app/controllers/places_controller.rb +34 -0
  42. data/test/dummy/app/controllers/works_controller.rb +37 -0
  43. data/test/dummy/app/helpers/application_helper.rb +2 -0
  44. data/test/dummy/app/helpers/artists_helper.rb +2 -0
  45. data/test/dummy/app/helpers/places_helper.rb +2 -0
  46. data/test/dummy/app/helpers/works_helper.rb +2 -0
  47. data/test/dummy/app/models/artist.rb +20 -0
  48. data/test/dummy/app/models/place.rb +8 -0
  49. data/test/dummy/app/models/work.rb +13 -0
  50. data/test/dummy/app/views/artists/_form.html.erb +29 -0
  51. data/test/dummy/app/views/artists/edit.html.erb +1 -0
  52. data/test/dummy/app/views/artists/index.html.erb +39 -0
  53. data/test/dummy/app/views/artists/new.html.erb +1 -0
  54. data/test/dummy/app/views/layouts/_custom_images_list.html.erb +6 -0
  55. data/test/dummy/app/views/layouts/application.html.erb +27 -0
  56. data/test/dummy/app/views/places/_form.html.erb +12 -0
  57. data/test/dummy/app/views/places/edit.html.erb +1 -0
  58. data/test/dummy/app/views/places/index.html.erb +32 -0
  59. data/test/dummy/app/views/places/new.html.erb +1 -0
  60. data/test/dummy/app/views/works/_form.html.erb +18 -0
  61. data/test/dummy/app/views/works/edit.html.erb +1 -0
  62. data/test/dummy/app/views/works/index.html.erb +32 -0
  63. data/test/dummy/app/views/works/new.html.erb +1 -0
  64. data/test/dummy/config/application.rb +24 -0
  65. data/test/dummy/config/boot.rb +10 -0
  66. data/test/dummy/config/database.yml +22 -0
  67. data/test/dummy/config/environment.rb +5 -0
  68. data/test/dummy/config/environments/development.rb +26 -0
  69. data/test/dummy/config/environments/production.rb +49 -0
  70. data/test/dummy/config/environments/test.rb +35 -0
  71. data/test/dummy/config/initializers/attachment_magick_setup.rb +12 -0
  72. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  73. data/test/dummy/config/initializers/inflections.rb +10 -0
  74. data/test/dummy/config/initializers/mime_types.rb +5 -0
  75. data/test/dummy/config/initializers/secret_token.rb +7 -0
  76. data/test/dummy/config/initializers/session_store.rb +8 -0
  77. data/test/dummy/config/locales/en.yml +5 -0
  78. data/test/dummy/config/mongoid.yml +18 -0
  79. data/test/dummy/config/routes.rb +15 -0
  80. data/test/dummy/config.ru +4 -0
  81. data/test/dummy/db/migrate/20110310155855_create_places.rb +13 -0
  82. data/test/dummy/db/migrate/20110310210525_attachment_magick_migration.rb +18 -0
  83. data/test/dummy/db/schema.rb +33 -0
  84. data/test/dummy/public/404.html +26 -0
  85. data/test/dummy/public/422.html +26 -0
  86. data/test/dummy/public/500.html +26 -0
  87. data/test/dummy/public/favicon.ico +0 -0
  88. data/test/dummy/public/images/little_girl.jpg +0 -0
  89. data/test/dummy/public/images/swfupload/cancelbutton.gif +0 -0
  90. data/test/dummy/public/javascripts/application.js +60 -0
  91. data/test/dummy/public/javascripts/jquery-ui.js +763 -0
  92. data/test/dummy/public/javascripts/jquery.js +7179 -0
  93. data/test/dummy/public/javascripts/jquery.min.js +167 -0
  94. data/test/dummy/public/javascripts/rails.js +137 -0
  95. data/test/dummy/public/javascripts/swfupload/handlers.js +384 -0
  96. data/test/dummy/public/javascripts/swfupload/swfupload.js +1132 -0
  97. data/test/dummy/public/javascripts/swfupload/swfupload.swf +0 -0
  98. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  99. data/test/dummy/public/stylesheets/attachment_magick.css +10 -0
  100. data/test/dummy/public/stylesheets/grid.css +491 -0
  101. data/test/dummy/public/stylesheets/swfupload.css +108 -0
  102. data/test/dummy/public/stylesheets/text.css +15 -0
  103. data/test/dummy/script/rails +6 -0
  104. data/test/integration/navigation_test.rb +7 -0
  105. data/test/support/integration_case.rb +5 -0
  106. data/test/test_helper.rb +48 -0
  107. metadata +283 -0
@@ -0,0 +1,384 @@
1
+ $(document).ready(function() {
2
+ attachmentMagick.startup();
3
+ });
4
+
5
+ var attachmentMagick = {
6
+ startup: function(){
7
+ this.elementKey = $('#attachmentmagick_key');
8
+ this.data_attachment = this.elementKey.attr('data_attachment');
9
+ this.data_partial = $('#attachmentmagick_partial').attr('data-partial') || "";
10
+ this.elementSortable = $(".attachmentSortable:first");
11
+
12
+ if ( $('#attachmentProgressContainer') ) { attachmentMagick.prepareImageUpload( this.data_attachment, this.data_partial ); }
13
+ $('.remove_image').live('click', function(){ attachmentMagick.removeImage( $(this) ); });
14
+ $('.video_upload').click(function(){ attachmentMagick.uploadVideo() });
15
+ $('.tiny_add_image').live('click', function(){ attachmentMagick.addImageToTiny( $(this) ); });
16
+ this.elementSortable.sortable({ update: function(event, ui){ attachmentMagick.updateImageList(); }});
17
+ },
18
+ removeImage: function(el){
19
+ var $attach_image = el.parents('.attachment_magick_image')
20
+ var $image = $attach_image.find("img:first");
21
+ var image_id = $attach_image.find("input[type='hidden']:first").val();
22
+ var url_path = "/attachment_magick/images/"+image_id+"/"+this.data_attachment
23
+
24
+ $.ajax({
25
+ type: "DELETE",
26
+ url: url_path,
27
+
28
+ success: function(data){
29
+ $image.fadeOut(250, function(){ $(this).parents('.attachment_magick_image').remove(); })
30
+ }
31
+ });
32
+ },
33
+ updateImageList: function(el){
34
+ var sort = this.elementSortable.sortable('toArray');
35
+ var array = new Array();
36
+
37
+ for( var i = 0; i < sort.length; i++ ){ array.push( sort[i].split('_').pop() ); };
38
+
39
+ $.ajax({
40
+ type: "POST",
41
+ url: "/attachment_magick/images/update_sortable",
42
+ data: {images: array, data_attachment: this.data_attachment}
43
+ });
44
+ },
45
+ prepareImageUpload: function(data_attachment, data_partial){
46
+ var swfu = new SWFUpload({
47
+ upload_url : '/attachment_magick/images/',
48
+ post_params : { 'data_attachment' : data_attachment, 'data_partial' : data_partial },
49
+
50
+ file_size_limit: '20 MB',
51
+ file_types: '*.jpg; *.png; *.gif; *.jpeg',
52
+ file_types_description: 'Images Files',
53
+ file_upload_limit : 0,
54
+
55
+ file_queue_error_handler: fileQueueError,
56
+ file_dialog_complete_handler: fileDialogComplete,
57
+ upload_progress_handler: uploadProgress,
58
+ upload_error_handler: uploadError,
59
+ upload_success_handler: uploadSuccess,
60
+ upload_complete_handler: uploadComplete,
61
+
62
+ button_placeholder_id: 'attachmentButton',
63
+ button_width: 160,
64
+ button_height: 16,
65
+ button_text : '<span class="button">BROWSE...</span>',
66
+ button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 11pt; border:1px solid #000;} .buttonSmall { font-size: 10pt; }',
67
+ button_text_top_padding: 0,
68
+ button_text_left_padding: 0,
69
+ button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
70
+ button_cursor: SWFUpload.CURSOR.HAND,
71
+
72
+ flash_url: '/javascripts/swfupload/swfupload.swf',
73
+ custom_settings: { upload_target : 'attachmentProgressContainer' },
74
+ debug: false
75
+ });
76
+
77
+ return swfu;
78
+ },
79
+ uploadVideo: function(){
80
+ var $el = $("#image_source");
81
+ var method = 'post';
82
+ var form_action = '/attachment_magick/images';
83
+ var form_data = $el.val();
84
+
85
+ if (form_data.trim() == "")
86
+ return false
87
+
88
+ $.ajax({
89
+ type: method,
90
+ url: form_action,
91
+ data: {"source" : form_data, data_attachment: this.data_attachment, data_partial: this.data_partial},
92
+
93
+ success: function(data){
94
+ $('#'+attachmentMagick.elementKey.val()+"").append(data);
95
+ $el.attr('value', "");
96
+ attachmentMagick.updateImageList();
97
+ }
98
+ });
99
+ }
100
+ }
101
+
102
+ function fileQueueError(file, errorCode, message) {
103
+ try {
104
+ var imageName = "error.gif";
105
+ var errorName = "";
106
+ if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
107
+ errorName = "Muitos arquivos na fila ao mesmo tempo.";
108
+ }
109
+
110
+ if (errorName !== "") {
111
+ alert(errorName);
112
+ return;
113
+ }
114
+
115
+ switch (errorCode) {
116
+ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
117
+ imageName = "zerobyte.gif";
118
+ break;
119
+ case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
120
+ imageName = "toobig.gif";
121
+ break;
122
+ case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
123
+ case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
124
+ default:
125
+ alert(message);
126
+ break;
127
+ }
128
+
129
+ addImage("/images/swfupload/" + imageName);
130
+
131
+ } catch (ex) {
132
+ this.debug(ex);
133
+ }
134
+
135
+ }
136
+
137
+ function fileDialogComplete(numFilesSelected, numFilesQueued) {
138
+ try {
139
+ if (numFilesQueued > 0) {
140
+ this.startUpload();
141
+ }
142
+ } catch (ex) {
143
+ this.debug(ex);
144
+ }
145
+ }
146
+
147
+ function uploadProgress(file, bytesLoaded) {
148
+
149
+ try {
150
+ var percent = Math.ceil((bytesLoaded / file.size) * 100);
151
+
152
+ var progress = new FileProgress(file, this.customSettings.upload_target);
153
+ progress.setProgress(percent);
154
+ if (percent === 100) {
155
+ progress.setStatus("Criando thumbnail...");
156
+ progress.toggleCancel(false, this);
157
+ } else {
158
+ progress.setStatus("Fazendo upload...");
159
+ progress.toggleCancel(true, this);
160
+ }
161
+ } catch (ex) {
162
+ this.debug(ex);
163
+ }
164
+ }
165
+
166
+ function uploadSuccess(file, serverData) {
167
+ try {
168
+ var progress = new FileProgress(file, this.customSettings.upload_target);
169
+
170
+ addImagePublisher(serverData)
171
+ progress.setStatus("Thumbnail criado.");
172
+ progress.toggleCancel(false);
173
+
174
+ } catch (ex) {
175
+ this.debug(ex);
176
+ }
177
+ }
178
+
179
+ function uploadComplete(file) {
180
+ try {
181
+ /* I want the next upload to continue automatically so I'll call startUpload here */
182
+
183
+ if (this.getStats().files_queued > 0) {
184
+ this.startUpload();
185
+ } else {
186
+ var progress = new FileProgress(file, this.customSettings.upload_target);
187
+ progress.setComplete();
188
+ progress.setStatus("Todas imagens recebidas.");
189
+ progress.toggleCancel(false);
190
+ update_img_index();
191
+ }
192
+ } catch (ex) {
193
+ this.debug(ex);
194
+ }
195
+ }
196
+
197
+ function uploadError(file, errorCode, message) {
198
+ var imageName = "error.gif";
199
+ var progress;
200
+ try {
201
+ switch (errorCode) {
202
+ case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
203
+ try {
204
+ progress = new FileProgress(file, this.customSettings.upload_target);
205
+ progress.setCancelled();
206
+ progress.setStatus("Cancelado");
207
+ progress.toggleCancel(false);
208
+ }
209
+ catch (ex1) {
210
+ this.debug(ex1);
211
+ }
212
+ break;
213
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
214
+ try {
215
+ progress = new FileProgress(file, this.customSettings.upload_target);
216
+ progress.setCancelled();
217
+ progress.setStatus("Parado");
218
+ progress.toggleCancel(true);
219
+ }
220
+ catch (ex2) {
221
+ this.debug(ex2);
222
+ }
223
+ case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
224
+ imageName = "uploadlimit.gif";
225
+ break;
226
+ default:
227
+ alert(message);
228
+ break;
229
+ }
230
+
231
+ addImage("/images/swfupload/" + imageName);
232
+
233
+ } catch (ex3) {
234
+ this.debug(ex3);
235
+ }
236
+
237
+ }
238
+
239
+ function addImagePublisher(serverData){
240
+ $('#'+attachmentMagick.elementKey.val()+"").prepend(serverData);
241
+ attachmentMagick.updateImageList( $('#'+attachmentMagick.elementKey.val()+"") );
242
+ }
243
+
244
+ function addImage(src) {
245
+ var newImg = document.createElement("img");
246
+ newImg.style.margin = "5px";
247
+
248
+ document.getElementById("thumbnails").appendChild(newImg);
249
+
250
+ if (newImg.filters) {
251
+ try {
252
+ newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0;
253
+ } catch (e) {
254
+ // If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
255
+ newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')';
256
+ }
257
+ } else {
258
+ newImg.style.opacity = 0;
259
+ }
260
+
261
+ newImg.onload = function () {
262
+ fadeIn(newImg, 0);
263
+ };
264
+ newImg.src = src;
265
+ }
266
+
267
+ function fadeIn(element, opacity) {
268
+ var reduceOpacityBy = 5;
269
+ var rate = 30; // 15 fps
270
+
271
+ if (opacity < 100) {
272
+ opacity += reduceOpacityBy;
273
+ if (opacity > 100) {
274
+ opacity = 100;
275
+ }
276
+
277
+ if (element.filters) {
278
+ try {
279
+ element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity;
280
+ } catch (e) {
281
+ // If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
282
+ element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')';
283
+ }
284
+ } else {
285
+ element.style.opacity = opacity / 100;
286
+ }
287
+ }
288
+
289
+ if (opacity < 100) {
290
+ setTimeout(function () {
291
+ fadeIn(element, opacity);
292
+ }, rate);
293
+ }
294
+ }
295
+
296
+
297
+ /* ******************************************
298
+ * FileProgress Object
299
+ * Control object for displaying file info
300
+ * ****************************************** */
301
+ function FileProgress(file, targetID) {
302
+ this.fileProgressID = "divFileProgress";
303
+
304
+ this.fileProgressWrapper = document.getElementById(this.fileProgressID);
305
+ if (!this.fileProgressWrapper) {
306
+ this.fileProgressWrapper = document.createElement("div");
307
+ this.fileProgressWrapper.className = "progressWrapper";
308
+ this.fileProgressWrapper.id = this.fileProgressID;
309
+
310
+ this.fileProgressElement = document.createElement("div");
311
+ this.fileProgressElement.className = "progressContainer";
312
+
313
+ var progressCancel = document.createElement("a");
314
+ progressCancel.className = "progressCancel";
315
+ progressCancel.href = "#";
316
+ progressCancel.style.visibility = "hidden";
317
+ progressCancel.appendChild(document.createTextNode(" "));
318
+
319
+ var progressText = document.createElement("div");
320
+ progressText.className = "progressName";
321
+ progressText.appendChild(document.createTextNode(file.name));
322
+
323
+ var progressBar = document.createElement("div");
324
+ progressBar.className = "progressBarInProgress";
325
+
326
+ var progressStatus = document.createElement("div");
327
+ progressStatus.className = "progressBarStatus";
328
+ progressStatus.innerHTML = "&nbsp;";
329
+
330
+ this.fileProgressElement.appendChild(progressCancel);
331
+ this.fileProgressElement.appendChild(progressText);
332
+ this.fileProgressElement.appendChild(progressStatus);
333
+ this.fileProgressElement.appendChild(progressBar);
334
+
335
+ this.fileProgressWrapper.appendChild(this.fileProgressElement);
336
+
337
+ document.getElementById(targetID).appendChild(this.fileProgressWrapper);
338
+ fadeIn(this.fileProgressWrapper, 0);
339
+
340
+ } else {
341
+ this.fileProgressElement = this.fileProgressWrapper.firstChild;
342
+ this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name;
343
+ }
344
+
345
+ this.height = this.fileProgressWrapper.offsetHeight;
346
+
347
+ }
348
+ FileProgress.prototype.setProgress = function (percentage) {
349
+ this.fileProgressElement.className = "progressContainer green";
350
+ this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
351
+ this.fileProgressElement.childNodes[3].style.width = percentage + "%";
352
+ };
353
+ FileProgress.prototype.setComplete = function () {
354
+ this.fileProgressElement.className = "progressContainer blue";
355
+ this.fileProgressElement.childNodes[3].className = "progressBarComplete";
356
+ this.fileProgressElement.childNodes[3].style.width = "";
357
+
358
+ };
359
+ FileProgress.prototype.setError = function () {
360
+ this.fileProgressElement.className = "progressContainer red";
361
+ this.fileProgressElement.childNodes[3].className = "progressBarError";
362
+ this.fileProgressElement.childNodes[3].style.width = "";
363
+
364
+ };
365
+ FileProgress.prototype.setCancelled = function () {
366
+ this.fileProgressElement.className = "progressContainer";
367
+ this.fileProgressElement.childNodes[3].className = "progressBarError";
368
+ this.fileProgressElement.childNodes[3].style.width = "";
369
+
370
+ };
371
+ FileProgress.prototype.setStatus = function (status) {
372
+ this.fileProgressElement.childNodes[2].innerHTML = status;
373
+ };
374
+
375
+ FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) {
376
+ this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
377
+ if (swfuploadInstance) {
378
+ var fileID = this.fileProgressID;
379
+ this.fileProgressElement.childNodes[0].onclick = function () {
380
+ swfuploadInstance.cancelUpload(fileID);
381
+ return false;
382
+ };
383
+ }
384
+ };