sufia 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -3
  3. data/History.md +16 -0
  4. data/app/assets/javascripts/sufia.js +2 -0
  5. data/app/assets/javascripts/sufia/batch_select_all.js +57 -128
  6. data/app/controllers/batch_controller.rb +4 -5
  7. data/app/controllers/concerns/sufia/users_controller_behavior.rb +2 -2
  8. data/app/controllers/contact_form_controller.rb +2 -24
  9. data/app/controllers/dashboard_controller.rb +1 -66
  10. data/app/controllers/single_use_link_controller.rb +3 -2
  11. data/app/helpers/generic_file_helper.rb +1 -4
  12. data/app/models/checksum_audit_log.rb +1 -1
  13. data/app/views/_footer.html.erb +2 -4
  14. data/app/views/batch_edits/_check_all.html.erb +3 -8
  15. data/app/views/batch_edits/_delete_selected.html.erb +1 -1
  16. data/app/views/batch_edits/edit.html.erb +2 -3
  17. data/app/views/dashboard/_facet_pagination.html.erb +2 -2
  18. data/app/views/generic_files/_asset_permissions_denial_flash.html.erb +1 -1
  19. data/app/views/generic_files/_asset_saved_flash.html.erb +1 -1
  20. data/app/views/generic_files/_asset_updated_flash.html.erb +1 -1
  21. data/app/views/generic_files/_media_display.html.erb +1 -1
  22. data/app/views/generic_files/edit.html.erb +1 -1
  23. data/app/views/generic_files/show.html.erb +1 -1
  24. data/app/views/single_use_link/generate_download.html.erb +1 -1
  25. data/app/views/single_use_link/generate_show.html.erb +1 -1
  26. data/app/views/single_use_link/show.html.erb +1 -1
  27. data/app/views/users/_trophy_edit.html.erb +1 -1
  28. data/app/views/users/show.html.erb +1 -1
  29. data/features/browse_dashboard_files.feature +1 -4
  30. data/features/display_dashboard.feature +1 -4
  31. data/features/step_definitions/scholarsphere.rb +1 -1
  32. data/lib/sufia.rb +4 -1
  33. data/lib/sufia/batch_edits_controller_behavior.rb +3 -4
  34. data/lib/sufia/contact_form_controller_behavior.rb +45 -0
  35. data/lib/sufia/dashboard_controller_behavior.rb +92 -0
  36. data/lib/sufia/downloads_controller_behavior.rb +6 -39
  37. data/lib/sufia/files_controller_behavior.rb +7 -7
  38. data/lib/sufia/generic_file.rb +3 -5
  39. data/lib/sufia/generic_file/web_form.rb +15 -0
  40. data/lib/sufia/jobs/batch_update_job.rb +1 -2
  41. data/lib/sufia/jobs/transcode_audio_job.rb +2 -3
  42. data/lib/sufia/jobs/unzip_job.rb +22 -13
  43. data/lib/sufia/model_methods.rb +6 -0
  44. data/lib/sufia/version.rb +1 -1
  45. data/spec/controllers/batch_edits_controller_spec.rb +22 -2
  46. data/spec/controllers/downloads_controller_spec.rb +9 -15
  47. data/spec/controllers/generic_files_controller_spec.rb +32 -0
  48. data/spec/controllers/single_use_link_controller_spec.rb +2 -1
  49. data/spec/controllers/users_controller_spec.rb +13 -0
  50. data/spec/models/generic_file_spec.rb +41 -0
  51. data/spec/support/Gemfile +1 -0
  52. data/sufia.gemspec +1 -1
  53. metadata +7 -6
  54. data/app/views/static/versions.html.erb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c1ede98424a5850d9fc61805d683d009adc137f
4
- data.tar.gz: b4b58df9eb918d41e5852a5afd4917f7771849d8
3
+ metadata.gz: c996c5fa4051c743da19c5d5f6bb7a9cc68d696e
4
+ data.tar.gz: 6254959c903a88cfb98bd79cad26bbd34a9c6d6d
5
5
  SHA512:
6
- metadata.gz: a15c15aa6703dfe883f75db875fa8362f6fb3dc3b5589549a75475dfc2b5fbfb7a8ee41bb9bcabadf1c8dbc3f2ef5fb3c41517a60ea046382afdc3f5f81ba291
7
- data.tar.gz: 6af364e8b6a156ca8fdbbe0dcee00c994192e088fb9a662b087dfb47de2386975534d3c96fa769fcc2bcc61644b78416dc73e0fbc279db85f687ed861e68c235
6
+ metadata.gz: a53f0c3971b91c537eb2df04cc6bd007936aedb42369ea39eab11c3257f8ecdd64be4e7ccb4b16dc20c0aa3b119e7fefbcaf7d32c4553e380192b4374093f4d2
7
+ data.tar.gz: dc0110f641efaf867351a92ca8377b1af250faedf4bf4923560df235cb05b5424eb3837849f04485eeb0175341bce4b6e44c0b298f6010d0febbc652a057938f
data/Gemfile CHANGED
@@ -10,13 +10,13 @@ group :development, :test do
10
10
  gem 'activerecord-import', '0.3.0'
11
11
  gem 'sqlite3'
12
12
  gem 'selenium-webdriver'
13
- gem 'rspec-rails', '~> 2.12.0'
13
+ gem 'rspec-rails', '~> 2.13.1'
14
14
  gem 'cucumber-rails', '~> 1.0', :require => false
15
15
  gem 'database_cleaner'
16
16
  gem 'devise'
17
- gem 'capybara', '~>1.1.3'
17
+ gem 'capybara', '~>2.1.0'
18
18
  gem 'bcrypt-ruby'
19
19
  gem "jettywrapper"
20
- gem "factory_girl_rails", "~> 4.1.0"
20
+ gem "factory_girl_rails", "~> 4.2.1"
21
21
  gem "simplecov", :require => false
22
22
  end # (leave this comment here to catch a stray line inserted by blacklight!)
data/History.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # History of Sufia releases
2
2
 
3
+ ## 1.3.0
4
+ * Depends on Hydra::Controller::DownloadBehavior
5
+ * Upgraded to hydra-batch-edit 1.1 which includes session-less batches in hydra-collections
6
+ * Moved most of the Dashboard behavior into Sufia::DashboardBehavior to enable overriding
7
+ * Added Model to_s instead of using display_title
8
+ * Added after delivery hook to contact form controller
9
+ * Removed the version page
10
+ * various bug fixes
11
+
12
+
13
+ ## 1.2.0
14
+ * DownloadController uses load_instance_from_solr for speed improvement
15
+ * Raise a AccessDenied error if a download is not allowed rather than show an image.
16
+ * Autoload the datastreams directory
17
+ * Set default variables (fits_path, id_namespace) in the engine config.
18
+
3
19
  ## 1.1.0
4
20
  * Allows a user to deposit on behalf of another user
5
21
  * Tweaks dashboard UI to be less busy: actions now in dropdown button
@@ -44,6 +44,8 @@ limitations under the License.
44
44
  //= require sufia/batch_select_all
45
45
  //= require sufia/multiForm
46
46
  //= require sufia/edit_metadata
47
+ //= require hydra/batch_select
48
+ //= require hydra_collections
47
49
 
48
50
  //over ride the blacklight default to submit
49
51
  //form when sort by or show per page change
@@ -2,7 +2,7 @@
2
2
  function toggleButtons(forceOn, otherPage ){
3
3
  forceOn = typeof forceOn !== 'undefined' ? forceOn : false
4
4
  otherPage = typeof otherPage !== 'undefined' ? otherPage : !window.batch_part_on_other_page;
5
- var n = $(".batch_toggle:checked").length;
5
+ var n = $(".batch_document_selector:checked").length;
6
6
  if ((n>0) || (forceOn)) {
7
7
  $('.batch-select-all').show();
8
8
  $('#batch-edit').show();
@@ -13,8 +13,16 @@
13
13
  $("body").css("cursor", "auto");
14
14
  }
15
15
 
16
+
17
+ // change the state of a cog menu item and add or remove the check beside it
18
+ // using on or off instead of true or false
16
19
  function toggleState (obj, state) {
17
- if (state == 'on'){
20
+ toggleStateBool(obj, state == 'on');
21
+ }
22
+
23
+ // change the state of a cog menu item and add or remove the check beside it
24
+ function toggleStateBool (obj, state) {
25
+ if (state){
18
26
  obj.attr("data-state", 'on');
19
27
  obj.find('a i').addClass('icon-ok');
20
28
  }else {
@@ -24,148 +32,70 @@
24
32
 
25
33
  }
26
34
 
27
- function check_all_page(e) {
28
- var checked = $("#check_all")[0]['checked'];
29
-
30
- // only check the current page
31
- var timeout = 0;
32
- var timeoutInc = 60;
33
-
34
- $("input[type='checkbox'].batch_toggle").each(function(index, value) {
35
- // check each individual box
36
- var ck = value['checked'];
37
- console.log("status for ");
38
- console.log(value);
39
- // not the same state click the box
40
- if (checked != ck) {
41
- console.log("click it");
42
- window.parent.setTimeout(function(){value.click();},timeout);
43
- }
44
- timeout+=timeoutInc;
45
- });
46
- window.parent.setTimeout(toggleButtons,timeout+500);
47
- $("#check_all").attr('checked', checked);
48
- }
49
35
 
50
- function clear_batch () {
51
- var url = '<%=clear_batch_edits_path %>';
52
- var clearState = $.ajax({
53
- headers: {
54
- Accept : "application/javascript",
55
- },
56
- type: 'PUT',
57
- url: url,
58
- async: false,
36
+ // check all the check boxes on the page
37
+ function check_all_page(e) {
38
+ // get the check box state
39
+ var checked = $("#check_all")[0]['checked'];
40
+
41
+ // check each individual box
42
+ $("input[type='checkbox'].batch_document_selector").each(function(index, value) {
43
+ value['checked'] = checked;
59
44
  });
60
-
45
+ toggleButtons();
46
+
47
+ // set menu check marks
48
+ toggleStateBool($("[data-behavior='batch-edit-select-page']"),checked);
49
+ toggleStateBool($("[data-behavior='batch-edit-select-none']"),!checked);
50
+
61
51
  }
62
-
63
- function set_all_checkboxes(checked){
64
- $("input[type='checkbox'].batch_toggle").each(function(){
65
- $(this).attr('checked', checked);
66
-
67
- // make sure the form is set correctly
68
- form = $($(this).parent()[0]);
69
- if (checked) {
70
- form.find("input[name=_method]").val("delete");
71
-
72
- } else {
73
- form.find("input[name=_method]").val("put");
74
- }
75
- });
76
-
52
+
53
+ // turn page selection on or off
54
+ // state == true for on
55
+ function select_page ( state) {
56
+ // check everything on the current page on or off based on state
57
+ $("#check_all").attr('checked', state);
58
+ check_all_page();
77
59
  }
78
-
79
60
 
80
61
  $(document).ready(function() {
81
62
 
63
+ // check the select all page cog menu item and select the entire page
82
64
  $("[data-behavior='batch-edit-select-page']").bind('click', function(e) {
83
- $("body").css("cursor", "progress");
84
65
  e.preventDefault();
85
- $("#check_all").attr('checked', true);
86
- toggleState($(this),'on');
87
- toggleState($("[data-behavior='batch-edit-select-all']"),'off');
88
- toggleState($("[data-behavior='batch-edit-select-none']"),'off');
89
- clear_batch();
90
-
91
- // uncheck everything on the current page
92
- set_all_checkboxes(false);
93
-
94
- // check everything on the current page
95
- check_all_page();
96
-
97
- });
98
-
99
- $("[data-behavior='batch-edit-select-all']").bind('click', function(e) {
100
- $("body").css("cursor", "progress");
101
- e.preventDefault();
102
- $("#check_all").attr('checked', true);
103
- toggleState($(this), 'on');
104
- toggleState($("[data-behavior='batch-edit-select-page']"),'off');
105
- toggleState($("[data-behavior='batch-edit-select-none']"),'off');
106
- var url = '<%=all_batch_edits_path %>';
107
- var clearState = $.ajax({
108
- headers: {
109
- Accept : "application/javascript",
110
- },
111
- type: 'PUT',
112
- url: url,
113
- async: false,
114
- });
115
-
116
- // show that update on the local screen
117
- set_all_checkboxes(true)
118
- $("body").css("cursor", "auto");
119
- toggleButtons(true);
66
+ select_page(true);
120
67
  });
121
68
 
69
+ // check the select none cog menu item and de-select the entire page
122
70
  $("[data-behavior='batch-edit-select-none']").bind('click', function(e) {
123
- $("body").css("cursor", "progress");
124
- e.preventDefault();
125
- $("#check_all").attr('checked', false);
126
- toggleState($(this), 'on');
127
- toggleState($("[data-behavior='batch-edit-select-page']"),'off');
128
- toggleState($("[data-behavior='batch-edit-select-all']"),'off');
129
- clear_batch();
130
-
131
- // show that update on the local screen
132
- set_all_checkboxes(false)
133
- $("body").css("cursor", "auto");
134
- toggleButtons(false, true);
71
+ e.preventDefault();
72
+ select_page(false);
135
73
  });
136
-
137
74
 
138
-
139
- // check all buttons
75
+ // check all check boxes
140
76
  $("#check_all").bind('click', check_all_page);
141
-
142
77
 
143
- $(".batch_toggle").bind('click', function(e) {
144
-
145
- // if we are unchecking a box remove the group selections
146
- if ($(e.currentTarget).attr('checked') != "checked") {
147
- toggleState($("[data-behavior='batch-edit-select-all']"),'off');
148
- toggleState($("[data-behavior='batch-edit-select-page']"),'off');
149
- toggleState($("[data-behavior='batch-edit-select-none']"),'off');
150
- $("#check_all").attr('checked', false);
151
- }
152
- // checking a single box see if we need to turn on one of the groups
153
- else {
154
- var n = $(".batch_toggle:checked").length;
155
- if (n == window.document_list_count) {
156
- $("#check_all").attr('checked', true);
157
- if (!window.batch_part_on_other_page) {
158
- toggleState($("[data-behavior='batch-edit-select-page']"),'on');
159
- } else if ((n + window.batch_size_on_other_page) == window.result_set_size){
160
- toggleState($("[data-behavior='batch-edit-select-all']"),'on');
161
- }
162
- } else {
163
- if ((n + window.batch_size_on_other_page) == 0){
164
- toggleState($("[data-behavior='batch-edit-select-none']"),'on');
165
- }
166
- }
167
- }
78
+ // toggle button on or off based on boxes being clicked
79
+ $(".batch_document_selector").bind('click', function(e) {
80
+ toggleButtons();
81
+ });
82
+
83
+ // toggle the state of the select boxes in the cog menu if all buttons are
84
+ $(".batch_document_selector").bind('click', function(e) {
85
+
86
+ // count the check boxes currently checked
87
+ var selectedCount = $(".batch_document_selector:checked").length;
88
+
89
+ // toggle the cog menu check boxes
90
+ toggleStateBool($("[data-behavior='batch-edit-select-page']"),selectedCount == window.document_list_count);
91
+ toggleStateBool($("[data-behavior='batch-edit-select-none']"),selectedCount == 0);
92
+
93
+ // toggle the check all check box
94
+ $("#check_all").attr('checked', (selectedCount == window.document_list_count));
95
+
168
96
  });
97
+
98
+ if ($("#check_all").length > 0) select_page(false);
169
99
 
170
100
  });
171
101
 
@@ -173,7 +103,6 @@ $(document).ready(function() {
173
103
  function setup_buttontoggle(checkbox) {
174
104
  checkbox.bind('click', function(e) {
175
105
  e.preventDefault();
176
- toggleButtons();
177
106
  });
178
107
  }
179
108
 
@@ -25,7 +25,7 @@ class BatchController < ApplicationController
25
25
  @generic_file = GenericFile.new
26
26
  @generic_file.creator = current_user.name
27
27
  @generic_file.title = @batch.generic_files.map(&:label)
28
- initialize_fields(@generic_file)
28
+ @generic_file.initialize_fields
29
29
  end
30
30
 
31
31
  def update
@@ -42,9 +42,8 @@ class BatchController < ApplicationController
42
42
 
43
43
  # override this method if you need to initialize more complex RDF assertions (b-nodes)
44
44
  def initialize_fields(file)
45
- file.terms_for_editing.each do |key|
46
- # if value is empty, we create an one element array to loop over for output
47
- file[key] = [''] if file[key].empty?
48
- end
45
+ file.initialize_fields
49
46
  end
47
+
48
+ ActiveSupport::Deprecation.deprecate_methods(BatchController, :initialize_fields)
50
49
  end
@@ -55,7 +55,7 @@ module Sufia::UsersControllerBehavior
55
55
  delete_trophy = params.keys.reject{|k,v|k.slice(0,'remove_trophy'.length)!='remove_trophy'}
56
56
  delete_trophy = delete_trophy.map{|v| v.slice('remove_trophy_'.length..-1)}
57
57
  delete_trophy.each do | smash_trophy |
58
- Trophy.where(user_id: current_user.id, generic_file_id: smash_trophy.slice("#{Sufia::Engine.config.id_namespace}:".length..-1)).each.map(&:delete)
58
+ Trophy.where(user_id: current_user.id, generic_file_id: smash_trophy).each.map(&:delete)
59
59
  end
60
60
  Sufia.queue.push(UserEditProfileEventJob.new(@user.user_key))
61
61
  redirect_to sufia.profile_path(URI.escape(@user.to_s,'@.')), notice: "Your profile has been updated"
@@ -74,7 +74,7 @@ module Sufia::UsersControllerBehavior
74
74
  t = Trophy.create(:generic_file_id => params[:file_id], :user_id => current_user.id)
75
75
  return false unless t.persisted?
76
76
  else
77
- t.delete
77
+ t.destroy
78
78
  #TODO do this better says Mike
79
79
  return false if t.persisted?
80
80
  end
@@ -13,27 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  class ContactFormController < ApplicationController
16
-
17
- def new
18
- @contact_form = ContactForm.new
19
- end
20
-
21
- def create
22
- @contact_form = ContactForm.new(params[:contact_form])
23
- @contact_form.request = request
24
- # not spam and a valid form
25
- logger.warn "*** MARK ***"
26
- if @contact_form.deliver
27
- flash.now[:notice] = 'Thank you for your message!'
28
- render :new
29
- else
30
- flash[:error] = 'Sorry, this message was not sent successfully. '
31
- flash[:error] << @contact_form.errors.full_messages.map { |s| s.to_s }.join(",")
32
- render :new
33
- end
34
- rescue
35
- flash[:error] = 'Sorry, this message was not delivered.'
36
- render :new
37
- end
38
-
39
- end
16
+ include Sufia::ContactFormControllerBehavior
17
+ end
@@ -14,70 +14,5 @@
14
14
 
15
15
  require 'blacklight/catalog'
16
16
  class DashboardController < ApplicationController
17
- include Hydra::BatchEditBehavior
18
- include Blacklight::Catalog
19
- include Blacklight::Configurable # comply with BL 3.7
20
- include Hydra::Controller::ControllerBehavior
21
- include ActionView::Helpers::DateHelper
22
- include BlacklightAdvancedSearch::ParseBasicQ
23
- include BlacklightAdvancedSearch::Controller
24
-
25
- # This is needed as of BL 3.7
26
- self.copy_blacklight_config_from(CatalogController)
27
-
28
- before_filter :authenticate_user!
29
- before_filter :enforce_show_permissions, :only=>:show
30
- before_filter :enforce_viewing_context_for_show_requests, :only=>:show
31
-
32
- # This applies appropriate access controls to all solr queries (the internal method of this is overidden bellow to only include edit files)
33
- DashboardController.solr_search_params_logic += [:add_access_controls_to_solr_params]
34
- # This filters out objects that you want to exclude from search results, like FileAssets
35
- DashboardController.solr_search_params_logic += [:exclude_unwanted_models]
36
-
37
- def index
38
- extra_head_content << view_context.auto_discovery_link_tag(:rss, sufia.url_for(params.merge(:format => 'rss')), :title => "RSS for results")
39
- extra_head_content << view_context.auto_discovery_link_tag(:atom, sufia.url_for(params.merge(:format => 'atom')), :title => "Atom for results")
40
- (@response, @document_list) = get_search_results
41
- @user = current_user
42
- @events = @user.events(100)
43
- @last_event_timestamp = @user.events.first[:timestamp].to_i || 0 rescue 0
44
- @filters = params[:f] || []
45
-
46
- # adding a key to the session so that the history will be saved so that batch_edits select all will work
47
- search_session[:dashboard] = true
48
- respond_to do |format|
49
- format.html { save_current_search_params }
50
- format.rss { render :layout => false }
51
- format.atom { render :layout => false }
52
- end
53
-
54
- # set up some parameters for allowing the batch controls to show appropiately
55
- @max_batch_size = 80
56
- count_on_page = @document_list.count {|doc| batch.index(doc.id)}
57
- @disable_select_all = @document_list.count > @max_batch_size
58
- batch_size = batch.uniq.size
59
- @result_set_size = @response.response["numFound"]
60
- @empty_batch = batch.empty?
61
- @all_checked = (count_on_page == @document_list.count)
62
- @entire_result_set_selected = @response.response["numFound"] == batch_size
63
- @batch_size_on_other_page = batch_size - count_on_page
64
- @batch_part_on_other_page = (@batch_size_on_other_page) > 0
65
- end
66
-
67
- def activity
68
- # reverse events since we're prepending rows. without reverse, old events wind up first
69
- events = current_user.events.reverse
70
- # filter events to include only those that have occurred since params[:since]
71
- events.select! { |event| event[:timestamp].to_i > params[:since].to_i } if params[:since]
72
- # return the event, a formatted date string, and a numerical timestamp
73
- render :json => events.map { |event| [event[:action], "#{time_ago_in_words(Time.at(event[:timestamp].to_i))} ago", event[:timestamp].to_i] }
74
- rescue
75
- render :json => []
76
- end
77
-
78
- protected
79
- # show only files with edit permissions in lib/hydra/access_controls_enforcement.rb apply_gated_discovery
80
- def discovery_permissions
81
- ["edit"]
82
- end
17
+ include Sufia::DashboardControllerBehavior
83
18
  end
@@ -4,7 +4,7 @@ class SingleUseLinkController < DownloadsController
4
4
  before_filter :authenticate_user!, :except => [:download, :show]
5
5
  before_filter :find_file, :only => [:generate_download, :generate_show]
6
6
  before_filter :authorize_user!, :only => [:generate_download, :generate_show]
7
- skip_filter :normalize_identifier
7
+ skip_filter :normalize_identifier, :load_asset, :load_datastream
8
8
  prepend_before_filter :normalize_identifier, :except => [:download, :show]
9
9
  rescue_from Sufia::SingleUseError, :with => :render_single_use_error
10
10
 
@@ -37,7 +37,8 @@ class SingleUseLinkController < DownloadsController
37
37
  not_found if link.path != sufia.download_path(id)
38
38
 
39
39
  # send the data content
40
- asset = GenericFile.find(id)
40
+ @asset = GenericFile.load_instance_from_solr(id)
41
+ load_datastream
41
42
  send_content(asset)
42
43
  end
43
44