spud_photos 0.1.5 → 0.9.0

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.
Files changed (43) hide show
  1. data/README.markdown +22 -2
  2. data/Rakefile +2 -14
  3. data/app/assets/javascripts/spud/admin/photos.js +36 -50
  4. data/app/assets/stylesheets/spud/admin/photos.css +1 -0
  5. data/app/controllers/photo_albums_controller.rb +6 -0
  6. data/app/controllers/photo_galleries_controller.rb +6 -0
  7. data/app/controllers/spud/admin/photo_albums_controller.rb +1 -0
  8. data/app/controllers/spud/admin/photo_galleries_controller.rb +1 -0
  9. data/app/controllers/spud/admin/photos_controller.rb +1 -0
  10. data/app/models/spud_photo.rb +4 -2
  11. data/app/models/spud_photo_sweeper.rb +33 -0
  12. data/app/views/spud/admin/photos/_form.html.erb +0 -5
  13. data/lib/spud_photos/configuration.rb +4 -1
  14. data/lib/spud_photos/version.rb +1 -1
  15. metadata +154 -74
  16. data/test/dummy/README.rdoc +0 -261
  17. data/test/dummy/Rakefile +0 -7
  18. data/test/dummy/app/assets/javascripts/application.js +0 -15
  19. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  20. data/test/dummy/app/controllers/application_controller.rb +0 -3
  21. data/test/dummy/app/helpers/application_helper.rb +0 -2
  22. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  23. data/test/dummy/config/application.rb +0 -56
  24. data/test/dummy/config/boot.rb +0 -10
  25. data/test/dummy/config/database.yml +0 -15
  26. data/test/dummy/config/environment.rb +0 -5
  27. data/test/dummy/config/environments/development.rb +0 -37
  28. data/test/dummy/config/environments/production.rb +0 -67
  29. data/test/dummy/config/environments/test.rb +0 -37
  30. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  31. data/test/dummy/config/initializers/inflections.rb +0 -15
  32. data/test/dummy/config/initializers/mime_types.rb +0 -5
  33. data/test/dummy/config/initializers/secret_token.rb +0 -7
  34. data/test/dummy/config/initializers/session_store.rb +0 -8
  35. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  36. data/test/dummy/config/locales/en.yml +0 -5
  37. data/test/dummy/config/routes.rb +0 -4
  38. data/test/dummy/config.ru +0 -4
  39. data/test/dummy/public/404.html +0 -26
  40. data/test/dummy/public/422.html +0 -26
  41. data/test/dummy/public/500.html +0 -25
  42. data/test/dummy/public/favicon.ico +0 -0
  43. data/test/dummy/script/rails +0 -6
data/README.markdown CHANGED
@@ -30,7 +30,7 @@ Spud Photos accepts the following configuration options:
30
30
  :large => '400x400#',
31
31
  :huge => '600x600'
32
32
  }
33
- self.paperclip_storage = :filesystem #use :s3 to use s3 storage (aws gem required)
33
+ config.paperclip_storage = :filesystem #use :s3 to use s3 storage (aws gem required)
34
34
  config.s3_credentials = "#{Rails.root}/config/s3.yml"
35
35
  config.storage_path = ":rails_root/public/system/spud_photos/:id/:style/:basename.:extension"
36
36
  config.storage_url = "/system/spud_photos/:id/:style/:basename.:extension"
@@ -52,4 +52,24 @@ __NOTE:__ The built-in views are likely to undergo changes as features are added
52
52
 
53
53
 
54
54
  [1]:https://github.com/davydotcom/spud_core_admin
55
- [2]:https://github.com/thoughtbot/paperclip
55
+ [2]:https://github.com/thoughtbot/paperclip
56
+
57
+ Testing
58
+ -----------------
59
+
60
+ Spud uses RSpec for testing. Get the tests running with a few short commands:
61
+
62
+ 1. Create and migrate the databases:
63
+
64
+ rake db:create
65
+ rake db:migrate
66
+
67
+ 2. Load the schema in to the test database:
68
+
69
+ rake app:db:test:prepare
70
+
71
+ 3. Run the tests with RSpec
72
+
73
+ rspec spec
74
+
75
+ After the tests have completed the current code coverage stats is available by opening ```/coverage/index.html``` in a browser.
data/Rakefile CHANGED
@@ -20,21 +20,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
20
  rdoc.rdoc_files.include('lib/**/*.rb')
21
21
  end
22
22
 
23
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
24
  load 'rails/tasks/engine.rake'
25
25
 
26
-
27
-
28
26
  Bundler::GemHelper.install_tasks
29
27
 
30
- require 'rake/testtask'
31
-
32
- Rake::TestTask.new(:test) do |t|
33
- t.libs << 'lib'
34
- t.libs << 'test'
35
- t.pattern = 'test/**/*_test.rb'
36
- t.verbose = false
37
- end
38
-
39
-
40
- task :default => :test
28
+ require 'rake'
@@ -14,12 +14,14 @@ Spud.Admin.Photos = new function(){
14
14
  $('body').on('submit', '#spud_admin_photo_album_form', self.submittedPhotoAlbumForm);
15
15
  $('body').on('submit', '#spud_admin_photo_gallery_form', self.submittedPhotoGalleryForm);
16
16
  $('body').on('submit', '#spud_admin_photo_form', self.submittedPhotoForm);
17
- $('body').on('click', '.spud_admin_photos_btn_remove', self.clickedPhotoRemoveFromAlbum)
17
+ $('body').on('click', '.spud_admin_photos_btn_remove', self.clickedPhotoRemoveFromAlbum);
18
18
  $('body').on('click', '.spud_admin_photo_ui_thumbs_selectable .spud_admin_photo_ui_thumb', self.selectedPhotoUiThumb);
19
19
  $('body').on('click', '#spud_admin_photo_album_action_library', self.clickedPhotoLibrary);
20
20
  $('body').on('click', '#spud_admin_photo_album_action_upload, .spud_admin_photo .spud_admin_photos_btn_edit', self.clickedPhotoAddOrEdit);
21
+ $('body').on('click', '.spud_admin_photo_library_add_selected', self.addSelectedPhotosFromLibrary);
22
+ $('body').on('click', '.spud_admin_photo_library_delete_selected', self.deleteSelectedPhotosFromLibrary);
21
23
 
22
- // html5 drag and drop file
24
+ // html5 drag and drop file
23
25
  if(typeof(FormData) != 'undefined' && typeof(XMLHttpRequest) != 'undefined' && (droparea = document.getElementById('spud_admin_photo_upload_queue'))){
24
26
  html5upload = true;
25
27
  $('#spud_admin_photo_upload_queue').show();
@@ -43,7 +45,7 @@ Spud.Admin.Photos = new function(){
43
45
 
44
46
  this.submittedPhotoGalleryForm = function(e){
45
47
  $('#spud_admin_photo_albums_available .spud_admin_photo_ui_thumb').remove();
46
- }
48
+ };
47
49
 
48
50
  this.clickedPhotoRemoveFromAlbum = function(e){
49
51
  $(this).parents('.spud_admin_photo_ui_thumb').fadeOut(200, function(){
@@ -68,7 +70,7 @@ Spud.Admin.Photos = new function(){
68
70
  var target = $('#spud_admin_photos_selected, #spud_admin_photos');
69
71
  target.prepend(html);
70
72
  }
71
- $('#dialog').dialog('close');
73
+ hideModalDialog();
72
74
  };
73
75
 
74
76
  this.selectedPhotoUiThumb = function(e){
@@ -102,14 +104,15 @@ Spud.Admin.Photos = new function(){
102
104
  });
103
105
  };
104
106
 
105
- /*
107
+ /*
106
108
  * Single-Photo Form Upload
107
109
  -------------------------------- */
108
110
 
109
111
  this.submittedPhotoForm = function(e){
110
112
  // disable submit button
111
- var submit = $(this).find('input[type=submit]');
112
- submit.attr('disabled', 'disabled').val(submit.attr('data-loading-text'));
113
+ // not working in updated bootstrap!
114
+ // var submit = $(this).find('input[type=submit]');
115
+ // submit.attr('disabled', 'disabled').val(submit.attr('data-loading-text'));
113
116
 
114
117
  if(html5upload){
115
118
  // create a FormData object and attach form values
@@ -120,20 +123,21 @@ Spud.Admin.Photos = new function(){
120
123
  fd.append('spud_photo[title]', form.find('#spud_photo_title').val());
121
124
  fd.append('spud_photo[caption]', form.find('#spud_photo_caption').val());
122
125
 
123
- // progress bar to send events to
126
+ // progress bar to send events to
127
+ var progressBar;
124
128
  var file = form.find('#spud_photo_photo')[0].files[0];
125
129
  if(file){
126
- var progressBar = self.progressBarForUpload(file.fileName);
130
+ progressBar = self.progressBarForUpload(file.fileName);
127
131
  fd.append('spud_photo[photo]', file);
128
- form.find('.form-actions').before(progressBar);
132
+ form.append(progressBar);
129
133
  }
130
134
  else{
131
- var progressBar = self.progressBarForUpload('');
135
+ progressBar = self.progressBarForUpload('');
132
136
  }
133
137
 
134
138
  // send FormData object as ajax request
135
139
  var xhr = new XMLHttpRequest();
136
- xhr.upload.addEventListener('progress', function(e){ self.onPhotoUploadProgress(e, progressBar) }, false);
140
+ xhr.upload.addEventListener('progress', function(e){ self.onPhotoUploadProgress(e, progressBar); }, false);
137
141
  xhr.addEventListener('load', function(e){ self.onPhotoUploadComplete(e, progressBar); }, false);
138
142
  xhr.addEventListener('error', function(e){ self.onPhotoUploadFailure(e, progressBar); }, false);
139
143
  xhr.addEventListener('abort', function(e){ self.onPhotoUploadCancel(e, progressBar); }, false);
@@ -144,7 +148,7 @@ Spud.Admin.Photos = new function(){
144
148
  }
145
149
  };
146
150
 
147
- /*
151
+ /*
148
152
  * Upload Progress Monitoring
149
153
  -------------------------------- */
150
154
 
@@ -184,18 +188,14 @@ Spud.Admin.Photos = new function(){
184
188
  var target = $('#spud_admin_photos_selected, #spud_admin_photos');
185
189
  target.prepend(photo.html).fadeIn(200);
186
190
  }
187
- $('#dialog').dialog('close');
191
+ hideModalDialog();
188
192
  }
189
193
  // validation error
190
194
  else{
191
- $('#dialog').html(photo.html);
195
+ $("#modal_window .modal-body").html(photo.html);
192
196
  }
193
197
  };
194
198
 
195
- this.onPhotoUploadCancel = function(e, progressBar){
196
-
197
- };
198
-
199
199
  this.onPhotoUploadCancel = function(e, progressBar){
200
200
  progressBar.find('.spud_admin_photo_progress_status').text('Done!');
201
201
  progressBar.find('.progress').addClass('progress-danger');
@@ -203,7 +203,7 @@ Spud.Admin.Photos = new function(){
203
203
 
204
204
  /*
205
205
  * Photo Upload/Edit Form
206
- ------------------------------- */
206
+ ------------------------------- */
207
207
  this.clickedPhotoAddOrEdit = function(e){
208
208
  var url = this.href;
209
209
  $.ajax({
@@ -214,17 +214,9 @@ Spud.Admin.Photos = new function(){
214
214
  };
215
215
 
216
216
  this.photoUploadFormLoaded = function(html){
217
- var dialog = $("#dialog");
218
- if(dialog.length == 0){
219
- dialog = $('<div id="dialog" style="display:hidden;"></div>').appendTo('body');
220
- }
221
- dialog.html(html);
222
- dialog.dialog({
223
- width: 500,
224
- modal: true,
225
- height: 'auto',
217
+ displayModalDialogWithOptions({
226
218
  title: 'Upload Photo',
227
- buttons: {}
219
+ html: html
228
220
  });
229
221
  };
230
222
 
@@ -242,11 +234,7 @@ Spud.Admin.Photos = new function(){
242
234
  };
243
235
 
244
236
  this.photoLibraryLoaded = function(html){
245
- var dialog = $("#dialog");
246
- if(dialog.length == 0){
247
- dialog = $('<div id="dialog" style="display:hidden;"></div>').appendTo('body');
248
- }
249
- dialog.html(html);
237
+ var dialog = $('#modal_window');
250
238
  $('#spud_admin_photos_selected .spud_admin_photo_ui_thumb').each(function(){
251
239
  var id = $(this).attr('id');
252
240
  var dupe = dialog.find('#'+id);
@@ -254,14 +242,12 @@ Spud.Admin.Photos = new function(){
254
242
  dupe.remove();
255
243
  }
256
244
  });
257
- dialog.dialog({
258
- width: 675,
259
- modal: true,
260
- height: 450,
245
+ displayModalDialogWithOptions({
261
246
  title: 'My Photo Library',
262
- buttons: {
263
- 'Add Selected': self.addSelectedPhotosFromLibrary,
264
- 'Delete Selected': self.deleteSelectedPhotosFromLibrary
247
+ html: html,
248
+ buttons:{
249
+ 'spud_admin_photo_library_add_selected btn-primary': 'Add Selected',
250
+ 'spud_admin_photo_library_delete_selected btn-danger': 'Delete Selected'
265
251
  }
266
252
  });
267
253
  };
@@ -272,11 +258,11 @@ Spud.Admin.Photos = new function(){
272
258
  .prependTo('#spud_admin_photos_selected')
273
259
  .hide()
274
260
  .fadeIn(200);
275
- $(this).dialog('close');
261
+ hideModalDialog();
276
262
  };
277
263
 
278
264
  this.deleteSelectedPhotosFromLibrary = function(e){
279
- var ids = $.map($('.spud_admin_photo_ui_thumb_selected'), function(val, i){
265
+ var ids = $.map($('.spud_admin_photo_ui_thumb_selected'), function(val, i){
280
266
  return $(val).attr('rel');
281
267
  });
282
268
  $.ajax({
@@ -289,10 +275,10 @@ Spud.Admin.Photos = new function(){
289
275
  });
290
276
  },
291
277
  error: function(jqXHR, textStatus, errorThrown){
292
- console.log('An error occurred:')
278
+ console.log('An error occurred:');
293
279
  console.log(arguments);
294
280
  }
295
- })
281
+ });
296
282
 
297
283
  };
298
284
 
@@ -307,7 +293,7 @@ Spud.Admin.Photos = new function(){
307
293
  this.stopDndPropagation = function(e){
308
294
  e.stopPropagation();
309
295
  e.preventDefault();
310
- }
296
+ };
311
297
 
312
298
  // add files to queue. starts queue if not started already
313
299
  this.droppedFile = function(e){
@@ -324,7 +310,7 @@ Spud.Admin.Photos = new function(){
324
310
  if(!this.fileQueueStarted){
325
311
  self.uploadNextPhoto();
326
312
  if(self.fileQueue.length > 0){
327
- self.uploadNextPhoto();
313
+ self.uploadNextPhoto();
328
314
  }
329
315
  }
330
316
  };
@@ -334,7 +320,7 @@ Spud.Admin.Photos = new function(){
334
320
  };
335
321
 
336
322
  this.uploadNextPhoto = function(){
337
- if(self.fileQueue.length == 0){
323
+ if(self.fileQueue.length === 0){
338
324
  self.fileQueueStarted = false;
339
325
  return;
340
326
  }
@@ -352,7 +338,7 @@ Spud.Admin.Photos = new function(){
352
338
  // send formdata as xhr
353
339
  var xhr = new XMLHttpRequest();
354
340
  xhr.upload.addEventListener('progress', function(e){ self.onPhotoUploadProgress(e, progressBar); }, false);
355
- xhr.addEventListener('load', function(e){ self.onQueuedPhotoUploadComplete(e, progressBar) }, false);
341
+ xhr.addEventListener('load', function(e){ self.onQueuedPhotoUploadComplete(e, progressBar); }, false);
356
342
  xhr.addEventListener('error', function(e){ self.onPhotoUploadFailure(e, progressBar); }, false);
357
343
  xhr.addEventListener('abort', function(e){ self.onPhotoUploadCancel(e, progressBar); }, false);
358
344
  xhr.open('POST', '/spud/admin/photos');
@@ -63,6 +63,7 @@
63
63
  white-space: nowrap;
64
64
  overflow: hidden;
65
65
  text-overflow: ellipsis;
66
+ margin: 0;
66
67
  }
67
68
  .spud_admin_photo_ui_thumb_controls{
68
69
  position: absolute;
@@ -3,6 +3,12 @@ class PhotoAlbumsController < ApplicationController
3
3
  respond_to :html, :json, :xml
4
4
  layout Spud::Photos.base_layout
5
5
 
6
+ after_filter :only => [:show, :index] do |c|
7
+ if Spud::Photos.enable_full_page_caching
8
+ c.cache_page(nil, nil, false)
9
+ end
10
+ end
11
+
6
12
  def index
7
13
  if params[:photo_gallery_id]
8
14
  @photo_gallery = SpudPhotoGallery.find_by_url_name(params[:photo_gallery_id])
@@ -3,6 +3,12 @@ class PhotoGalleriesController < ApplicationController
3
3
  respond_to :html, :json, :xml
4
4
  layout Spud::Photos.base_layout
5
5
 
6
+ after_filter :only => [:index] do |c|
7
+ if Spud::Photos.enable_full_page_caching
8
+ c.cache_page(nil, nil, false)
9
+ end
10
+ end
11
+
6
12
  def index
7
13
  @photo_galleries = SpudPhotoGallery.order('created_at desc')
8
14
  respond_with @photo_galleries
@@ -4,6 +4,7 @@ class Spud::Admin::PhotoAlbumsController < Spud::Admin::ApplicationController
4
4
  add_breadcrumb 'Photo Albums', :spud_admin_photo_albums_path
5
5
  respond_to :html, :json, :xml
6
6
  layout 'spud/admin/spud_photos'
7
+ cache_sweeper :spud_photo_sweeper, :only => [:create, :update, :destroy]
7
8
 
8
9
  def index
9
10
  @photo_albums = SpudPhotoAlbum.all
@@ -5,6 +5,7 @@ class Spud::Admin::PhotoGalleriesController < Spud::Admin::ApplicationController
5
5
  add_breadcrumb 'Photo Galleries', :spud_admin_photo_galleries_path
6
6
  respond_to :html, :json, :xml
7
7
  layout 'spud/admin/spud_photos'
8
+ cache_sweeper :spud_photo_sweeper, :only => [:create, :update, :destroy]
8
9
 
9
10
  def index
10
11
  @photo_galleries = SpudPhotoGallery.all
@@ -5,6 +5,7 @@ class Spud::Admin::PhotosController < Spud::Admin::ApplicationController
5
5
  before_filter :get_photo, :only => [:show, :edit, :update, :destroy]
6
6
  respond_to :html, :json, :xml, :js
7
7
  layout false
8
+ cache_sweeper :spud_photo_sweeper, :only => [:create, :update, :destroy]
8
9
 
9
10
  def index
10
11
  @photos = SpudPhoto.all
@@ -9,6 +9,7 @@ class SpudPhoto < ActiveRecord::Base
9
9
 
10
10
  has_attached_file :photo,
11
11
  :styles => lambda { |attachment| attachment.instance.dynamic_styles },
12
+ :convert_options => Spud::Photos.config.convert_options,
12
13
  :storage => Spud::Photos.paperclip_storage,
13
14
  :s3_credentials => Spud::Photos.s3_credentials,
14
15
  :url => Spud::Photos.storage_url,
@@ -17,9 +18,10 @@ class SpudPhoto < ActiveRecord::Base
17
18
  validates_attachment_presence :photo
18
19
 
19
20
  def dynamic_styles
21
+ compress = '-strip -density 72x72'
20
22
  admin_styles = {
21
- :spud_admin_small => '125x125#',
22
- :spud_admin_medium => '300x200'
23
+ :spud_admin_small => {:geometry => '125x125#', :convert_options => compress},
24
+ :spud_admin_medium => {:geometry => '300x200', :convert_options => compress}
23
25
  }
24
26
  return admin_styles.merge(Spud::Photos.config.photo_styles)
25
27
  end
@@ -0,0 +1,33 @@
1
+ class SpudPhotoSweeper < ActionController::Caching::Sweeper
2
+
3
+ observe :spud_photo, :spud_photo_album, :spud_photo_gallery
4
+
5
+ def after_create(record)
6
+ expire_cache_for(record)
7
+ end
8
+
9
+ def before_update(record)
10
+ expire_cache_for(record)
11
+ end
12
+
13
+ def after_destroy(record)
14
+ expire_cache_for(record)
15
+ end
16
+
17
+ private
18
+
19
+ def expire_cache_for(record)
20
+ if Spud::Photos.config.enable_full_page_caching
21
+ cache_path = File.join(ActionController::Base.page_cache_directory, Spud::Photos.config.base_path)
22
+ if File.directory?(cache_path)
23
+ FileUtils.rm_rf(cache_path)
24
+ end
25
+ if !Spud::Photos.config.page_caches_to_sweep.blank?
26
+ Spud::Photos.config.page_caches_to_sweep.each do |route|
27
+ expire_page(route)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -36,11 +36,6 @@
36
36
  <% end %>
37
37
  </fieldset>
38
38
 
39
- <div class="form-actions">
40
- <%= f.submit "Save Photo", :class=>"btn btn-primary form-btn", "data-loading-text" => "Saving..." %>
41
- <!--or <%=link_to "cancel", request.referer, :class => "btn" %> -->
42
- </div>
43
-
44
39
  <iframe id="spud_admin_photo_form_target" name="spud_admin_photo_form_target" style="display:none;"></iframe>
45
40
 
46
41
  <% end %>
@@ -1,12 +1,13 @@
1
1
  module Spud
2
2
  module Photos
3
3
  include ActiveSupport::Configurable
4
- config_accessor :photo_styles, :galleries_enabled, :base_layout, :base_path,:s3_credentials,:storage_path,:storage_url,:paperclip_storage
4
+ config_accessor :photo_styles, :convert_options, :galleries_enabled, :base_layout, :base_path,:s3_credentials,:storage_path,:storage_url,:paperclip_storage, :enable_full_page_caching, :page_caches_to_sweep
5
5
  self.photo_styles = {
6
6
  :small => '50x50#',
7
7
  :medium => '200x200#',
8
8
  :large => '400x400#'
9
9
  }
10
+ self.convert_options = {}
10
11
  self.galleries_enabled = false
11
12
  self.base_layout = 'application'
12
13
  self.base_path = 'photos'
@@ -14,5 +15,7 @@ module Spud
14
15
  self.s3_credentials = "#{Rails.root}/config/s3.yml"
15
16
  self.storage_path = ":rails_root/public/system/spud_photos/:id/:style/:basename.:extension"
16
17
  self.storage_url = "/system/spud_photos/:id/:style/:basename.:extension"
18
+ self.enable_full_page_caching = false
19
+ self.page_caches_to_sweep = []
17
20
  end
18
21
  end
@@ -1,5 +1,5 @@
1
1
  module Spud
2
2
  module Photos
3
- VERSION = "0.1.5"
3
+ VERSION = "0.9.0"
4
4
  end
5
5
  end