curation_concerns 0.12.0.pre1 → 0.12.0.pre2
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +24 -16
- data/Gemfile +0 -4
- data/README.md +14 -0
- data/RELEASING.md +2 -2
- data/Rakefile +2 -0
- data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +28 -0
- data/app/actors/curation_concerns/abstract_actor.rb +28 -0
- data/app/actors/curation_concerns/add_to_collection_actor.rb +38 -0
- data/app/actors/curation_concerns/apply_order_actor.rb +24 -0
- data/app/actors/curation_concerns/assign_identifier_actor.rb +7 -0
- data/app/actors/curation_concerns/assign_representative_actor.rb +18 -0
- data/app/actors/curation_concerns/attach_files_actor.rb +39 -0
- data/app/actors/curation_concerns/base_actor.rb +71 -0
- data/app/actors/curation_concerns/embargo_actor.rb +19 -0
- data/app/actors/curation_concerns/file_actor.rb +79 -0
- data/app/actors/curation_concerns/file_set_actor.rb +146 -0
- data/app/actors/curation_concerns/interpret_visibility_actor.rb +123 -0
- data/app/actors/curation_concerns/lease_actor.rb +19 -0
- data/app/actors/curation_concerns/root_actor.rb +17 -0
- data/app/actors/curation_concerns/work_actor_behavior.rb +8 -0
- data/app/assets/javascripts/curation_concerns/batch_select.js +42 -0
- data/app/assets/javascripts/curation_concerns/collections.js +13 -0
- data/app/assets/javascripts/curation_concerns/curation_concerns.js +2 -0
- data/app/assets/stylesheets/curation_concerns/_curation_concerns.scss +0 -3
- data/app/assets/stylesheets/curation_concerns/_modules.scss +1 -1
- data/app/assets/stylesheets/curation_concerns/_positioning.scss +3 -6
- data/app/assets/stylesheets/curation_concerns/_theme.scss +0 -39
- data/app/assets/stylesheets/curation_concerns/_typography.scss +0 -69
- data/app/assets/stylesheets/curation_concerns/modules/classify_work.scss +0 -2
- data/app/assets/stylesheets/curation_concerns/modules/collections.scss +4 -0
- data/app/assets/stylesheets/curation_concerns/modules/forms.scss +0 -4
- data/app/assets/stylesheets/curation_concerns/modules/site_actions.scss +34 -29
- data/app/assets/stylesheets/curation_concerns/modules/site_search.scss +0 -46
- data/app/assets/stylesheets/curation_concerns.scss +4 -0
- data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +166 -21
- data/app/controllers/concerns/curation_concerns/embargoes_controller_behavior.rb +1 -1
- data/app/controllers/concerns/curation_concerns/leases_controller_behavior.rb +1 -1
- data/app/controllers/concerns/curation_concerns/selects_collections.rb +65 -0
- data/app/forms/curation_concerns/forms/collection_edit_form.rb +0 -29
- data/app/forms/curation_concerns/forms/work_form.rb +2 -1
- data/app/helpers/batch_select_helper.rb +23 -0
- data/app/helpers/collections_helper.rb +4 -0
- data/app/helpers/curation_concerns/collections_helper.rb +2 -2
- data/app/helpers/curation_concerns/collections_helper_behavior.rb +56 -0
- data/app/helpers/curation_concerns/render_constraints_helper.rb +14 -35
- data/app/helpers/curation_concerns/title_helper.rb +4 -0
- data/app/indexers/curation_concerns/collection_indexer.rb +16 -0
- data/app/indexers/curation_concerns/file_set_indexer.rb +46 -0
- data/app/indexers/curation_concerns/work_indexer.rb +15 -0
- data/app/jobs/audit_job.rb +49 -0
- data/app/jobs/characterize_job.rb +11 -0
- data/app/jobs/create_derivatives_job.rb +21 -0
- data/app/jobs/import_url_job.rb +48 -0
- data/app/jobs/ingest_file_job.rb +30 -0
- data/app/jobs/ingest_local_file_job.rb +20 -0
- data/app/jobs/resolrize_job.rb +7 -0
- data/app/models/checksum_audit_log.rb +20 -0
- data/app/models/collection.rb +6 -0
- data/app/models/concerns/curation_concerns/ability.rb +49 -0
- data/app/models/concerns/curation_concerns/basic_metadata.rb +64 -0
- data/app/models/concerns/curation_concerns/collection.rb +16 -0
- data/app/models/concerns/curation_concerns/collection_behavior.rb +62 -0
- data/app/models/concerns/curation_concerns/file_set/belongs_to_works.rb +47 -0
- data/app/models/concerns/curation_concerns/file_set/derivatives.rb +65 -0
- data/app/models/concerns/curation_concerns/file_set/full_text_indexing.rb +11 -0
- data/app/models/concerns/curation_concerns/file_set/indexing.rb +14 -0
- data/app/models/concerns/curation_concerns/file_set/querying.rb +17 -0
- data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
- data/app/models/concerns/curation_concerns/has_representative.rb +13 -0
- data/app/models/concerns/curation_concerns/human_readable_type.rb +17 -0
- data/app/models/concerns/curation_concerns/naming.rb +17 -0
- data/app/models/concerns/curation_concerns/permissions/readable.rb +18 -0
- data/app/models/concerns/curation_concerns/permissions/writable.rb +34 -0
- data/app/models/concerns/curation_concerns/permissions.rb +7 -0
- data/app/models/concerns/curation_concerns/required_metadata.rb +30 -0
- data/app/models/concerns/curation_concerns/serializers.rb +13 -0
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +147 -0
- data/app/models/concerns/curation_concerns/user.rb +18 -0
- data/app/models/concerns/curation_concerns/with_file_sets.rb +37 -0
- data/app/models/concerns/curation_concerns/work_behavior.rb +45 -0
- data/app/models/curation_concerns/classify_concern.rb +49 -0
- data/app/models/curation_concerns/quick_classification_query.rb +38 -0
- data/app/models/single_use_link.rb +34 -0
- data/app/models/version_committer.rb +2 -0
- data/app/search_builders/curation_concerns/collection_member_search_builder.rb +1 -1
- data/app/search_builders/curation_concerns/collection_search_builder.rb +33 -0
- data/app/search_builders/curation_concerns/member_search_builder.rb +17 -0
- data/app/services/curation_concerns/derivative_path.rb +49 -0
- data/app/services/curation_concerns/file_set_audit_service.rb +105 -0
- data/app/services/curation_concerns/indexes_thumbnails.rb +30 -0
- data/app/services/curation_concerns/local_file_service.rb +10 -0
- data/app/services/curation_concerns/lock_manager.rb +39 -0
- data/app/services/curation_concerns/lockable.rb +16 -0
- data/app/services/curation_concerns/noid.rb +23 -0
- data/app/services/curation_concerns/persist_derivatives.rb +33 -0
- data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
- data/app/services/curation_concerns/repository_audit_service.rb +7 -0
- data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
- data/app/services/curation_concerns/time_service.rb +7 -0
- data/app/services/curation_concerns/versioning_service.rb +26 -0
- data/app/validators/has_one_title_validator.rb +8 -0
- data/app/views/batch_select/_add_button.html.erb +3 -0
- data/app/views/batch_select/_check_all.html.erb +4 -0
- data/app/views/batch_select/_tools.html.erb +10 -0
- data/app/views/catalog/_action_menu_partials/_collection.html.erb +3 -3
- data/app/views/catalog/_action_menu_partials/_default.html.erb +1 -1
- data/app/views/catalog/_document_list.html.erb +1 -1
- data/app/views/collections/_bookmark_control.html.erb +2 -0
- data/app/views/collections/_button_create_collection.html.erb +2 -0
- data/app/views/collections/_button_for_creating_empty_collection.html.erb +1 -1
- data/app/views/collections/_button_for_delete_collection.html.erb +4 -0
- data/app/views/collections/_button_for_remove_selected_from_collection.html.erb +8 -0
- data/app/views/collections/_button_for_update_collection.html.erb +4 -0
- data/app/views/collections/_button_remove_from_collection.html.erb +4 -0
- data/app/views/collections/_document_header.html.erb +9 -0
- data/app/views/collections/_edit_actions.html.erb +1 -1
- data/app/views/collections/_edit_descriptions.html.erb +1 -1
- data/app/views/collections/_form.html.erb +2 -2
- data/app/views/collections/_form_for_select_destination_collection.html.erb +21 -0
- data/app/views/collections/_form_to_add_member.html.erb +1 -1
- data/app/views/collections/_index_default.html.erb +2 -0
- data/app/views/collections/_index_header_default.html.erb +2 -0
- data/app/views/collections/_media_display.html.erb +1 -1
- data/app/views/collections/_paginate.html.erb +1 -1
- data/app/views/collections/_paginate_compact.html.erb +1 -0
- data/app/views/collections/_results_pagination.html.erb +9 -0
- data/app/views/collections/_search_collection_dashboard_form.html.erb +1 -1
- data/app/views/collections/_search_form.html.erb +1 -1
- data/app/views/collections/_search_results.html.erb +23 -0
- data/app/views/collections/_show_actions.html.erb +1 -1
- data/app/views/collections/_sort_and_per_page.html.erb +1 -1
- data/app/views/collections/_view_type_group.html.erb +1 -1
- data/app/views/collections/index.html.erb +9 -0
- data/app/views/collections/new.html.erb +3 -0
- data/app/views/curation_concerns/base/_form_permission.html.erb +10 -11
- data/app/views/curation_concerns/base/_form_permission_embargo.html.erb +1 -1
- data/app/views/curation_concerns/base/_form_permission_lease.html.erb +1 -1
- data/app/views/curation_concerns/base/_legally_binding_text.html.erb +7 -7
- data/app/views/curation_concerns/base/_related_files.html.erb +1 -1
- data/app/views/curation_concerns/base/_visibility.html.erb +2 -2
- data/app/views/curation_concerns/file_sets/_actions.html.erb +1 -1
- data/app/views/embargoes/_list_expired_active_embargoes.html.erb +1 -1
- data/app/views/error/single_use_error.html.erb +1 -1
- data/app/views/shared/_add_content.html.erb +17 -15
- data/app/views/shared/_brand_bar.html.erb +19 -10
- data/app/views/shared/_header.html.erb +2 -6
- data/app/views/shared/_my_actions.html.erb +28 -27
- data/app/views/shared/_site_actions.html.erb +5 -1
- data/app/views/shared/_site_search.html.erb +3 -2
- data/app/views/shared/_title_bar.html.erb +7 -16
- data/app/views/welcome/index.html.erb +2 -2
- data/config/locales/curation_concerns.en.yml +25 -1
- data/curation_concerns.gemspec +21 -5
- data/lib/curation_concerns/collections/accepts_batches.rb +53 -0
- data/lib/curation_concerns/collections/search_service.rb +57 -0
- data/lib/curation_concerns/collections.rb +10 -0
- data/lib/curation_concerns/configuration.rb +167 -0
- data/lib/curation_concerns/engine.rb +22 -1
- data/lib/curation_concerns/messages.rb +68 -0
- data/lib/curation_concerns/models.rb +42 -0
- data/lib/curation_concerns/name.rb +20 -0
- data/lib/curation_concerns/null_logger.rb +10 -0
- data/lib/curation_concerns/rails/routes.rb +1 -3
- data/lib/curation_concerns/version.rb +1 -1
- data/lib/curation_concerns.rb +2 -0
- data/lib/generators/curation_concerns/abstract_migration_generator.rb +31 -0
- data/lib/generators/curation_concerns/clamav_generator.rb +19 -0
- data/lib/generators/curation_concerns/collection_generator.rb +15 -0
- data/lib/generators/curation_concerns/install_generator.rb +1 -2
- data/lib/generators/curation_concerns/models_generator.rb +62 -0
- data/lib/generators/curation_concerns/templates/app/models/collection.rb +6 -0
- data/lib/generators/curation_concerns/templates/app/models/file_set.rb +4 -0
- data/lib/generators/curation_concerns/templates/config/clamav.rb +1 -0
- data/lib/generators/curation_concerns/templates/config/curation_concerns.rb +61 -0
- data/lib/generators/curation_concerns/templates/config/mime_types.rb +6 -0
- data/lib/generators/curation_concerns/templates/config/redis.yml +9 -0
- data/lib/generators/curation_concerns/templates/config/redis_config.rb +29 -0
- data/lib/generators/curation_concerns/templates/config/resque-pool.yml +1 -0
- data/lib/generators/curation_concerns/templates/config/resque_config.rb +6 -0
- data/lib/generators/curation_concerns/templates/curation_concerns.scss +3 -2
- data/lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb +19 -0
- data/lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb +12 -0
- data/lib/generators/curation_concerns/templates/migrations/create_version_committers.rb +15 -0
- data/lib/tasks/migrate.rake +11 -0
- data/lib/tasks/resque.rake +14 -0
- data/lib/tasks/solr_reindex.rake +8 -0
- data/spec/actors/curation_concerns/file_set_actor_spec.rb +31 -0
- data/spec/controllers/accepts_batches_controller_spec.rb +65 -0
- data/spec/controllers/collections_controller_spec.rb +272 -0
- data/spec/controllers/curation_concerns/collections_controller_spec.rb +1 -2
- data/spec/controllers/selects_collections_controller_spec.rb +109 -0
- data/spec/features/create_work_spec.rb +1 -1
- data/spec/features/work_generator_spec.rb +1 -1
- data/spec/forms/collection_edit_form_spec.rb +2 -9
- data/spec/forms/work_form_spec.rb +5 -0
- data/spec/helpers/collections_helper_spec.rb +129 -0
- data/spec/helpers/curation_concerns/collections_helper_spec.rb +2 -2
- data/spec/helpers/render_constraints_helper_spec.rb +23 -1
- data/spec/lib/curation_concerns/collections/search_service_spec.rb +33 -0
- data/spec/models/collection_spec.rb +165 -0
- data/spec/tasks/rake_spec.rb +1 -1
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- data/spec/views/curation_concerns/base/_form_permission.html.erb_spec.rb +4 -1
- data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +1 -0
- data/spec/views/shared/_add_content.html.erb_spec.rb +3 -3
- metadata +341 -24
- data/VERSION +0 -1
- data/app/assets/stylesheets/curation_concerns/_global-variables.scss +0 -5
- data/app/assets/stylesheets/curation_concerns/modules/multi_value_fields.scss +0 -52
- data/app/views/collections/_form_required_information.html.erb +0 -11
- data/tasks/release.rake +0 -93
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
.search-form {
|
|
2
|
-
position:relative;
|
|
3
|
-
|
|
4
|
-
.search-query,
|
|
5
|
-
.search-submit {
|
|
6
|
-
-moz-box-sizing: border-box;
|
|
7
|
-
box-sizing:border-box;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.search-query {
|
|
11
|
-
width:100%;
|
|
12
|
-
padding-left:.6em;
|
|
13
|
-
padding-right:12%;
|
|
14
|
-
height: 2.1em;
|
|
15
|
-
border-radius: $input-border-radius;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.search-submit {
|
|
19
|
-
padding:2px;
|
|
20
|
-
position:absolute;
|
|
21
|
-
right:2px;
|
|
22
|
-
text-align:center;
|
|
23
|
-
top:2px;
|
|
24
|
-
white-space:nowrap;
|
|
25
|
-
width:9%;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.search-query-form {
|
|
30
|
-
margin-bottom:.3em;
|
|
31
|
-
padding-left:1em;
|
|
32
|
-
|
|
33
|
-
.search-scope {
|
|
34
|
-
display:block;
|
|
35
|
-
line-height:1.5em;
|
|
36
|
-
margin-bottom:.3em;
|
|
37
|
-
|
|
38
|
-
input {
|
|
39
|
-
margin-top:0;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.label-text {
|
|
44
|
-
padding-left:.3em;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,54 +1,150 @@
|
|
|
1
1
|
module CurationConcerns
|
|
2
2
|
module CollectionsControllerBehavior
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
|
-
include Hydra::CollectionsControllerBehavior
|
|
5
4
|
include Blacklight::AccessControls::Catalog
|
|
6
5
|
|
|
6
|
+
include Blacklight::Base
|
|
7
|
+
include CurationConcerns::SelectsCollections
|
|
8
|
+
|
|
7
9
|
included do
|
|
8
10
|
before_action :filter_docs_with_read_access!, except: :show
|
|
11
|
+
before_action :remove_select_something_first_flash, except: :show
|
|
9
12
|
layout 'curation_concerns/1_column'
|
|
10
|
-
|
|
13
|
+
|
|
14
|
+
include CurationConcerns::Collections::AcceptsBatches
|
|
15
|
+
|
|
16
|
+
# This is needed as of BL 3.7
|
|
17
|
+
copy_blacklight_config_from(::CatalogController)
|
|
18
|
+
|
|
19
|
+
# Catch permission errors
|
|
20
|
+
rescue_from Hydra::AccessDenied, CanCan::AccessDenied do |exception|
|
|
21
|
+
if exception.action == :edit
|
|
22
|
+
redirect_to(collections.url_for(action: 'show'), alert: 'You do not have sufficient privileges to edit this document')
|
|
23
|
+
elsif current_user && current_user.persisted?
|
|
24
|
+
redirect_to root_url, alert: exception.message
|
|
25
|
+
else
|
|
26
|
+
session['user_return_to'] = request.url
|
|
27
|
+
redirect_to new_user_session_url, alert: exception.message
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# actions: audit, index, create, new, edit, show, update, destroy, permissions, citation
|
|
32
|
+
before_action :authenticate_user!, except: [:show]
|
|
33
|
+
load_and_authorize_resource except: [:index, :show], instance_name: :collection
|
|
11
34
|
|
|
12
35
|
class_attribute :presenter_class, :form_class
|
|
13
36
|
self.presenter_class = CurationConcerns::CollectionPresenter
|
|
14
37
|
self.form_class = CurationConcerns::Forms::CollectionEditForm
|
|
15
38
|
end
|
|
16
39
|
|
|
40
|
+
def index
|
|
41
|
+
# run the solr query to find the collections
|
|
42
|
+
query = collections_search_builder.with(params).query
|
|
43
|
+
@response = repository.search(query)
|
|
44
|
+
@document_list = @response.documents
|
|
45
|
+
end
|
|
46
|
+
|
|
17
47
|
def new
|
|
18
|
-
super
|
|
19
48
|
form
|
|
20
49
|
end
|
|
21
50
|
|
|
51
|
+
def show
|
|
52
|
+
presenter
|
|
53
|
+
query_collection_members
|
|
54
|
+
end
|
|
55
|
+
|
|
22
56
|
def edit
|
|
23
|
-
|
|
57
|
+
query_collection_members
|
|
58
|
+
find_collections
|
|
24
59
|
form
|
|
25
60
|
end
|
|
26
61
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
def after_create
|
|
63
|
+
form
|
|
64
|
+
respond_to do |format|
|
|
65
|
+
ActiveFedora::SolrService.instance.conn.commit
|
|
66
|
+
format.html { redirect_to collection_path(@collection), notice: 'Collection was successfully created.' }
|
|
67
|
+
format.json { render json: @collection, status: :created, location: @collection }
|
|
68
|
+
end
|
|
30
69
|
end
|
|
31
70
|
|
|
32
71
|
def after_create_error
|
|
33
72
|
form
|
|
34
|
-
|
|
73
|
+
|
|
74
|
+
respond_to do |format|
|
|
75
|
+
format.html { render action: 'new' }
|
|
76
|
+
format.json { render json: @collection.errors, status: :unprocessable_entity }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def create
|
|
81
|
+
@collection.apply_depositor_metadata(current_user.user_key)
|
|
82
|
+
add_members_to_collection unless batch.empty?
|
|
83
|
+
if @collection.save
|
|
84
|
+
after_create
|
|
85
|
+
else
|
|
86
|
+
after_create_error
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def after_update
|
|
91
|
+
if flash[:notice].nil?
|
|
92
|
+
flash[:notice] = 'Collection was successfully updated.'
|
|
93
|
+
end
|
|
94
|
+
respond_to do |format|
|
|
95
|
+
format.html { redirect_to collection_path(@collection) }
|
|
96
|
+
format.json { render json: @collection, status: :updated, location: @collection }
|
|
97
|
+
end
|
|
35
98
|
end
|
|
36
99
|
|
|
37
100
|
def after_update_error
|
|
38
101
|
form
|
|
39
102
|
query_collection_members
|
|
40
|
-
|
|
103
|
+
|
|
104
|
+
respond_to do |format|
|
|
105
|
+
format.html { render action: 'edit' }
|
|
106
|
+
format.json { render json: @collection.errors, status: :unprocessable_entity }
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def update
|
|
111
|
+
process_member_changes
|
|
112
|
+
if @collection.update(collection_params.except(:members))
|
|
113
|
+
after_update
|
|
114
|
+
else
|
|
115
|
+
after_update_error
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def after_destroy(id)
|
|
120
|
+
respond_to do |format|
|
|
121
|
+
format.html { redirect_to search_catalog_path, notice: 'Collection was successfully deleted.' }
|
|
122
|
+
format.json { render json: { id: id }, status: :destroyed, location: @collection }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def after_destroy_error(id)
|
|
127
|
+
respond_to do |format|
|
|
128
|
+
format.html { redirect_to search_catalog_path, notice: 'Collection could not be deleted.' }
|
|
129
|
+
format.json { render json: { id: id }, status: :destroy_error, location: @collection }
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def destroy
|
|
134
|
+
if @collection.destroy
|
|
135
|
+
after_destroy(params[:id])
|
|
136
|
+
else
|
|
137
|
+
after_destroy_error(params[:id])
|
|
138
|
+
end
|
|
41
139
|
end
|
|
42
140
|
|
|
43
|
-
# overriding the method in Hydra::Collections so the search builder can find the collection
|
|
44
141
|
def collection
|
|
45
142
|
action_name == 'show' ? @presenter : @collection
|
|
46
143
|
end
|
|
47
144
|
|
|
48
145
|
protected
|
|
49
146
|
|
|
50
|
-
def
|
|
51
|
-
super
|
|
147
|
+
def remove_select_something_first_flash
|
|
52
148
|
flash.delete(:notice) if flash.notice == 'Select something first'
|
|
53
149
|
end
|
|
54
150
|
|
|
@@ -81,25 +177,74 @@ module CurationConcerns
|
|
|
81
177
|
form_class.model_attributes(params[:collection])
|
|
82
178
|
end
|
|
83
179
|
|
|
180
|
+
def form
|
|
181
|
+
@form ||= form_class.new(@collection)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Queries Solr for members of the collection.
|
|
185
|
+
# Populates @response and @member_docs similar to Blacklight Catalog#index populating @response and @documents
|
|
84
186
|
def query_collection_members
|
|
85
187
|
params[:q] = params[:cq]
|
|
86
|
-
|
|
188
|
+
@response = repository.search(query_for_collection_members)
|
|
189
|
+
@member_docs = @response.documents
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# @return <Hash> a representation of the solr query that find the collection members
|
|
193
|
+
def query_for_collection_members
|
|
194
|
+
collection_member_search_builder.with(params_for_members_query).query
|
|
87
195
|
end
|
|
88
196
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
197
|
+
# You can override this method if you need to provide additional inputs to the search
|
|
198
|
+
# builder. For example:
|
|
199
|
+
# search_field: 'all_fields'
|
|
200
|
+
# @return <Hash> the inputs required for the collection member search builder
|
|
201
|
+
def params_for_members_query
|
|
202
|
+
params.symbolize_keys.merge(q: params[:cq])
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def collection_member_search_builder
|
|
206
|
+
@collection_member_search_builder ||= collection_member_search_builder_class.new(self).tap do |builder|
|
|
207
|
+
builder.current_ability = current_ability
|
|
93
208
|
end
|
|
94
209
|
end
|
|
95
210
|
|
|
96
|
-
def
|
|
97
|
-
|
|
211
|
+
def process_member_changes
|
|
212
|
+
case params[:collection][:members]
|
|
213
|
+
when 'add' then add_members_to_collection
|
|
214
|
+
when 'remove' then remove_members_from_collection
|
|
215
|
+
when 'move' then move_members_between_collections
|
|
216
|
+
when Array then assign_batch_to_collection
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def add_members_to_collection(collection = nil)
|
|
221
|
+
collection ||= @collection
|
|
222
|
+
collection.add_members batch
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def remove_members_from_collection
|
|
226
|
+
@collection.members.delete(batch.map { |pid| ActiveFedora::Base.find(pid) })
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def assign_batch_to_collection
|
|
230
|
+
@collection.members(true) # Force the members to get cached before (maybe) removing some of them
|
|
231
|
+
@collection.member_ids = batch
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def move_members_between_collections
|
|
235
|
+
destination_collection = ::Collection.find(params[:destination_collection_id])
|
|
236
|
+
remove_members_from_collection
|
|
237
|
+
add_members_to_collection(destination_collection)
|
|
238
|
+
if destination_collection.save
|
|
239
|
+
flash[:notice] = "Successfully moved #{batch.count} files to #{destination_collection.title} Collection."
|
|
240
|
+
else
|
|
241
|
+
flash[:error] = "An error occured. Files were not moved to #{destination_collection.title} Collection."
|
|
242
|
+
end
|
|
98
243
|
end
|
|
99
244
|
|
|
100
245
|
# Include 'catalog' and 'curation_concerns/base' in the search path for views
|
|
101
246
|
def _prefixes
|
|
102
247
|
@_prefixes ||= super + ['catalog', 'curation_concerns/base']
|
|
103
248
|
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
249
|
+
end # module CollectionsControllerBehavior
|
|
250
|
+
end # module Hydra
|
|
@@ -2,7 +2,7 @@ module CurationConcerns
|
|
|
2
2
|
module EmbargoesControllerBehavior
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
include CurationConcerns::ManagesEmbargoes
|
|
5
|
-
include
|
|
5
|
+
include CurationConcerns::Collections::AcceptsBatches
|
|
6
6
|
|
|
7
7
|
included do
|
|
8
8
|
skip_before_action :normalize_identifier, only: :update
|
|
@@ -2,7 +2,7 @@ module CurationConcerns
|
|
|
2
2
|
module LeasesControllerBehavior
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
include CurationConcerns::ManagesEmbargoes
|
|
5
|
-
include
|
|
5
|
+
include CurationConcerns::Collections::AcceptsBatches
|
|
6
6
|
|
|
7
7
|
included do
|
|
8
8
|
skip_before_action :normalize_identifier, only: :update
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module CurationConcerns::SelectsCollections
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
configure_blacklight do |config|
|
|
6
|
+
config.search_builder_class = CurationConcerns::CollectionSearchBuilder
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def access_levels
|
|
11
|
+
{ read: [:read, :edit], edit: [:edit] }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Return list of collections for which the current user has read access.
|
|
16
|
+
# Add this or find_collections_with_edit_access as a before filter on any page that shows the form_for_select_collection
|
|
17
|
+
#
|
|
18
|
+
# @return [Array<SolrDocument>] Solr documents for each collection the user has read access
|
|
19
|
+
def find_collections_with_read_access
|
|
20
|
+
find_collections(:read)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Return list of collections for which the current user has edit access. Optionally prepend with default
|
|
25
|
+
# that can be used in a select menu to instruct user to select a collection.
|
|
26
|
+
# Add this or find_collections_with_read_access as a before filter on any page that shows the form_for_select_collection
|
|
27
|
+
#
|
|
28
|
+
# @param [TrueClass|FalseClass] :include_default if true, prepends the default_option; otherwise, if false, returns only collections
|
|
29
|
+
# @param [Fixnum] :default_id for select menus, this is the id of the first selection representing the instructions
|
|
30
|
+
# @param [String] :default_title for select menus, this is the text displayed as the first item serving as instructions
|
|
31
|
+
#
|
|
32
|
+
# @return [Array<SolrDocument>] Solr documents for each collection the user has edit access, plus optional instructions
|
|
33
|
+
def find_collections_with_edit_access(include_default = false, default_id = -1, default_title = 'Select collection...')
|
|
34
|
+
find_collections(:edit)
|
|
35
|
+
default_option = SolrDocument.new(id: default_id, title_tesim: default_title)
|
|
36
|
+
@user_collections.unshift(default_option) if include_default
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Return list of collections matching the passed in access_level for the current user.
|
|
41
|
+
# @param [Symbol] :access_level one of :read or :edit
|
|
42
|
+
# @return [Array<SolrDocument>] Solr documents for each collection the user has the appropriate access level
|
|
43
|
+
def find_collections(access_level = nil)
|
|
44
|
+
# need to know the user if there is an access level applied otherwise we are just doing public collections
|
|
45
|
+
authenticate_user! unless access_level.blank?
|
|
46
|
+
|
|
47
|
+
# run the solr query to find the collections
|
|
48
|
+
query = collections_search_builder(access_level).with(q: '').query
|
|
49
|
+
response = repository.search(query)
|
|
50
|
+
|
|
51
|
+
# return the user's collections (or public collections if no access_level is applied)
|
|
52
|
+
@user_collections = response.documents
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def collections_search_builder_class
|
|
56
|
+
CurationConcerns::CollectionSearchBuilder
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def collections_search_builder(access_level = nil)
|
|
60
|
+
collections_search_builder_class.new(self).tap do |builder|
|
|
61
|
+
builder.current_ability = current_ability
|
|
62
|
+
builder.discovery_perms = access_levels[access_level] if access_level
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -18,35 +18,6 @@ module CurationConcerns
|
|
|
18
18
|
model_class.validators_on(key).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
# The form only supports a single value for title, so use the first
|
|
22
|
-
# @return [String] the first title
|
|
23
|
-
def title
|
|
24
|
-
model.title.first
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# The form only supports a single value for description, so use the first
|
|
28
|
-
# @return [String] the first description
|
|
29
|
-
def description
|
|
30
|
-
model.description.first
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# @param [Symbol] key the property to test for cardinality
|
|
34
|
-
# @return [FalseClass,TrueClass] whether the value on the form is singular or multipl
|
|
35
|
-
def self.multiple?(key)
|
|
36
|
-
return false if [:title, :description].include? key
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# @param [ActiveSupport::Parameters]
|
|
41
|
-
# @return [Hash] a hash suitable for populating Collection attributes.
|
|
42
|
-
def self.model_attributes(_)
|
|
43
|
-
attrs = super
|
|
44
|
-
# cast title and description back to multivalued
|
|
45
|
-
attrs[:title] = Array(attrs[:title]) if attrs[:title]
|
|
46
|
-
attrs[:description] = Array(attrs[:description]) if attrs[:description]
|
|
47
|
-
attrs
|
|
48
|
-
end
|
|
49
|
-
|
|
50
21
|
# @return [Hash] All generic files in the collection, file.to_s is the key, file.id is the value
|
|
51
22
|
def select_files
|
|
52
23
|
Hash[all_files]
|
|
@@ -6,7 +6,8 @@ module CurationConcerns
|
|
|
6
6
|
|
|
7
7
|
delegate :human_readable_type, :open_access?, :authenticated_only_access?,
|
|
8
8
|
:open_access_with_embargo_release_date?, :private_access?,
|
|
9
|
-
:embargo_release_date, :lease_expiration_date, :member_ids,
|
|
9
|
+
:embargo_release_date, :lease_expiration_date, :member_ids,
|
|
10
|
+
:visibility, to: :model
|
|
10
11
|
|
|
11
12
|
self.terms = [:title, :creator, :contributor, :description,
|
|
12
13
|
:tag, :rights, :publisher, :date_created, :subject, :language,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# View Helpers for Hydra Batch Edit functionality
|
|
2
|
+
module BatchSelectHelper
|
|
3
|
+
# determines if the given document id is in the batch
|
|
4
|
+
# def item_in_batch?(doc_id)
|
|
5
|
+
# session[:batch_document_ids] && session[:batch_document_ids].include?(doc_id) ? true : false
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
# Displays the batch edit tools. Put this in your search result page template. We recommend putting it in catalog/_sort_and_per_page.html.erb
|
|
9
|
+
def batch_select_tools
|
|
10
|
+
render partial: '/batch_select/tools'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Displays the button to select/deselect items for your batch. Call this in the index partial that's rendered for each search result.
|
|
14
|
+
# @param [Hash] document the Hash (aka Solr hit) for one Solr document
|
|
15
|
+
def button_for_add_to_batch(document)
|
|
16
|
+
render partial: '/batch_select/add_button', locals: { document: document }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Displays the check all button to select/deselect items for your batch. Put this in your search result page template. We put it in catalog/index.html
|
|
20
|
+
def batch_check_all(label = 'Use all results')
|
|
21
|
+
render partial: '/batch_select/check_all', locals: { label: label }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -14,8 +14,8 @@ module CurationConcerns::CollectionsHelper
|
|
|
14
14
|
# override hydra-collections
|
|
15
15
|
def link_to_remove_from_collection(document, label = 'Remove From Collection')
|
|
16
16
|
collection_id = @collection ? @collection.id : @presenter.id
|
|
17
|
-
link_to
|
|
18
|
-
|
|
17
|
+
link_to collection_path(collection_id, collection: { members: 'remove' },
|
|
18
|
+
batch_document_ids: [document.id]), method: :put do
|
|
19
19
|
icon('minus-sign') + ' ' + label
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# View Helpers for Hydra Collections functionality
|
|
2
|
+
module CurationConcerns
|
|
3
|
+
module CollectionsHelperBehavior
|
|
4
|
+
def has_collection_search_parameters?
|
|
5
|
+
!params[:cq].blank?
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Displays the Collections create collection button. Put this in your search result page template. We recommend putting it in catalog/_sort_and_per_page.html.erb
|
|
9
|
+
def button_for_create_collection(label = 'Create Collection')
|
|
10
|
+
render '/collections/button_create_collection', label: label
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Displays the Collections update collection button. Put this in your search result page template. We recommend putting it in catalog/_sort_and_per_page.html.erb
|
|
14
|
+
def button_for_update_collection(label = 'Update Collection', collection_id = 'collection_replace_id')
|
|
15
|
+
render '/collections/button_for_update_collection', label: label, collection_id: collection_id
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Displays the Collections delete collection button. Put this in your search result page for each collection found.
|
|
19
|
+
def button_for_delete_collection(collection, label = 'Delete Collection', confirm = 'Are you sure?')
|
|
20
|
+
render '/collections/button_for_delete_collection', collection: collection, label: label, confirm: confirm
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def button_for_remove_from_collection(collection, document, label = 'Remove From Collection')
|
|
24
|
+
render '/collections/button_remove_from_collection', collection: collection, label: label, document: document
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def button_for_remove_selected_from_collection(collection, label = 'Remove From Collection')
|
|
28
|
+
render '/collections/button_for_remove_selected_from_collection', collection: collection, label: label
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# add hidden fields to a form for removing a single document from a collection
|
|
32
|
+
def single_item_action_remove_form_fields(form, document)
|
|
33
|
+
single_item_action_form_fields(form, document, 'remove')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# add hidden fields to a form for adding a single document to a collection
|
|
37
|
+
def single_item_action_add_form_fields(form, document)
|
|
38
|
+
single_item_action_form_fields(form, document, 'add')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# add hidden fields to a form for performing an action on a single document on a collection
|
|
42
|
+
def single_item_action_form_fields(form, document, action)
|
|
43
|
+
render '/collections/single_item_action_fields', form: form, document: document, action: action
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def hidden_collection_members
|
|
47
|
+
erbout = ''
|
|
48
|
+
if params[:batch_document_ids].present?
|
|
49
|
+
params[:batch_document_ids].each do |batch_item|
|
|
50
|
+
erbout.concat hidden_field_tag('batch_document_ids[]', batch_item)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
erbout.html_safe
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -1,42 +1,21 @@
|
|
|
1
1
|
module CurationConcerns
|
|
2
2
|
module RenderConstraintsHelper
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
render_constraint_element(constraint_query_label(localized_params),
|
|
15
|
-
localized_params[:q],
|
|
16
|
-
classes: ['query'],
|
|
17
|
-
remove: url_for(localized_params.except(:search_field).merge(q: nil, action: 'index')))
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
# We can remove this method once we use Blacklight > 5.4.0
|
|
22
|
-
##
|
|
23
|
-
# Return a label for the currently selected search field.
|
|
24
|
-
# If no "search_field" or the default (e.g. "all_fields") is selected, then return nil
|
|
25
|
-
# Otherwise grab the label of the selected search field.
|
|
26
|
-
# @param [Hash] query parameters
|
|
27
|
-
# @return [String]
|
|
28
|
-
def constraint_query_label(localized_params = params)
|
|
29
|
-
label_for_search_field(localized_params[:search_field]) unless default_search_field?(localized_params[:search_field])
|
|
3
|
+
# This overrides Blacklight to remove the 'search_field' tag from the
|
|
4
|
+
# localized params when the query is cleared. This is because unlike
|
|
5
|
+
# Blacklight, there is no control to change the search_field in the
|
|
6
|
+
# curation_concerns UI
|
|
7
|
+
def remove_constraint_url(localized_params)
|
|
8
|
+
scope = localized_params.delete(:route_set) || self
|
|
9
|
+
options = localized_params.merge(q: nil, action: 'index')
|
|
10
|
+
.except(*fields_to_exclude_from_constraint_element)
|
|
11
|
+
options.permit!
|
|
12
|
+
scope.url_for(options)
|
|
30
13
|
end
|
|
31
14
|
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# @param [String] the currently selected search_field
|
|
37
|
-
# @return [Boolean]
|
|
38
|
-
def default_search_field?(selected_search_field)
|
|
39
|
-
selected_search_field.blank? || (default_search_field && selected_search_field == default_search_field[:key])
|
|
15
|
+
# @return [Array<Symbol>] a list of fields to remove on the render_constraint_element
|
|
16
|
+
# You can override this if you have different fields to remove
|
|
17
|
+
def fields_to_exclude_from_constraint_element
|
|
18
|
+
[:search_field]
|
|
40
19
|
end
|
|
41
20
|
end
|
|
42
21
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module CurationConcerns
|
|
2
|
+
class CollectionIndexer < Hydra::PCDM::CollectionIndexer
|
|
3
|
+
include IndexesThumbnails
|
|
4
|
+
STORED_LONG = Solrizer::Descriptor.new(:long, :stored)
|
|
5
|
+
|
|
6
|
+
def generate_solr_document
|
|
7
|
+
super.tap do |solr_doc|
|
|
8
|
+
# Makes Collections show under the "Collections" tab
|
|
9
|
+
Solrizer.set_field(solr_doc, 'generic_type', 'Collection', :facetable)
|
|
10
|
+
# Index the size of the collection in bytes
|
|
11
|
+
solr_doc[Solrizer.solr_name(:bytes, STORED_LONG)] = object.bytes
|
|
12
|
+
solr_doc['thumbnail_path_ss'] = thumbnail_path
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module CurationConcerns
|
|
2
|
+
class FileSetIndexer < ActiveFedora::IndexingService
|
|
3
|
+
include IndexesThumbnails
|
|
4
|
+
STORED_INTEGER = Solrizer::Descriptor.new(:integer, :stored)
|
|
5
|
+
|
|
6
|
+
def generate_solr_document
|
|
7
|
+
super.tap do |solr_doc|
|
|
8
|
+
solr_doc[Solrizer.solr_name('hasRelatedMediaFragment', :symbol)] = object.representative_id
|
|
9
|
+
solr_doc[Solrizer.solr_name('hasRelatedImage', :symbol)] = object.thumbnail_id
|
|
10
|
+
# Label is the actual file name. It's not editable by the user.
|
|
11
|
+
solr_doc[Solrizer.solr_name('label')] = object.label
|
|
12
|
+
solr_doc[Solrizer.solr_name('label', :stored_sortable)] = object.label
|
|
13
|
+
solr_doc[Solrizer.solr_name('file_format')] = file_format
|
|
14
|
+
solr_doc[Solrizer.solr_name('file_format', :facetable)] = file_format
|
|
15
|
+
solr_doc[Solrizer.solr_name(:file_size, STORED_INTEGER)] = object.file_size[0]
|
|
16
|
+
solr_doc['all_text_timv'] = object.full_text.content
|
|
17
|
+
solr_doc[Solrizer.solr_name('generic_work_ids', :symbol)] = object.generic_work_ids unless object.generic_work_ids.empty?
|
|
18
|
+
solr_doc['height_is'] = Integer(object.height.first) if object.height.present?
|
|
19
|
+
solr_doc['width_is'] = Integer(object.width.first) if object.width.present?
|
|
20
|
+
solr_doc[Solrizer.solr_name('mime_type', :stored_sortable)] = object.mime_type
|
|
21
|
+
solr_doc['thumbnail_path_ss'] = thumbnail_path
|
|
22
|
+
# Index the Fedora-generated SHA1 digest to create a linkage
|
|
23
|
+
# between files on disk (in fcrepo.binary-store-path) and objects
|
|
24
|
+
# in the repository.
|
|
25
|
+
solr_doc[Solrizer.solr_name('digest', :symbol)] = digest_from_content
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def digest_from_content
|
|
32
|
+
return unless object.original_file
|
|
33
|
+
object.original_file.digest.first.to_s
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def file_format
|
|
37
|
+
if object.mime_type.present? && object.format_label.present?
|
|
38
|
+
"#{object.mime_type.split('/').last} (#{object.format_label.join(', ')})"
|
|
39
|
+
elsif object.mime_type.present?
|
|
40
|
+
object.mime_type.split('/').last
|
|
41
|
+
elsif object.format_label.present?
|
|
42
|
+
object.format_label
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|