hyrax 5.0.1 → 5.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +7 -176
- data/.dassie/.env +8 -3
- data/.dassie/Gemfile +13 -2
- data/.dassie/app/controllers/hyrax/generic_work_resources_controller.rb +17 -0
- data/.dassie/app/controllers/hyrax/generic_works_controller.rb +7 -1
- data/.dassie/app/forms/generic_work_resource_form.rb +20 -0
- data/.dassie/app/indexers/generic_work_resource_indexer.rb +16 -0
- data/.dassie/app/models/admin_set_resource.rb +9 -0
- data/.dassie/app/models/collection_resource.rb +2 -0
- data/.dassie/app/models/file_set.rb +2 -0
- data/.dassie/app/models/generic_work_resource.rb +10 -0
- data/.dassie/app/views/hyrax/generic_work_resources/_generic_work_resource.html.erb +2 -0
- data/.dassie/config/analytics.yml +6 -1
- data/.dassie/config/application.rb +24 -0
- data/.dassie/config/initializers/hyrax.rb +13 -3
- data/.dassie/config/initializers/wings.rb +109 -0
- data/.dassie/config/metadata/generic_work_resource.yaml +22 -0
- data/.dassie/config/valkyrie_index.yml +4 -10
- data/.dassie/db/migrate/20240506070809_valkyrie_id_to_string.rb +5 -0
- data/.dassie/db/schema.rb +2 -2
- data/.dassie/spec/indexers/generic_work_resource_indexer_spec.rb +13 -0
- data/.dassie/spec/models/generic_work_resource_spec.rb +12 -0
- data/.dassie/spec/views/generic_work_resources/_generic_work_resource.html.erb_spec.rb +7 -0
- data/.dockerignore +6 -4
- data/.github/release.yml +3 -0
- data/.github/workflows/lint-build-test.yml +130 -0
- data/.github/workflows/test-results.yml +40 -0
- data/.koppie/.env +7 -5
- data/.koppie/Gemfile +12 -1
- data/.koppie/config/analytics.yml +6 -1
- data/.koppie/config/environments/test.rb +2 -0
- data/.koppie/config/initializers/1_valkyrie.rb +6 -2
- data/.koppie/config/solr.yml +1 -1
- data/.regen +1 -1
- data/.rubocop.yml +5 -0
- data/Dockerfile +16 -36
- data/Gemfile +2 -0
- data/app/assets/javascripts/hydra-editor/field_manager.es6 +187 -0
- data/app/assets/javascripts/hyrax/analytics_events.js +48 -24
- data/app/assets/javascripts/hyrax/collapse.js +4 -4
- data/app/assets/javascripts/hyrax/file_manager/save_manager.es6 +2 -0
- data/app/assets/javascripts/hyrax/search.js +2 -3
- data/app/assets/javascripts/hyrax/select_work_type.es6 +3 -1
- data/app/assets/javascripts/hyrax/uploader.js +20 -18
- data/app/assets/javascripts/hyrax.js +1 -0
- data/app/assets/stylesheets/_bootstrap-default-overrides.scss +4 -0
- data/app/assets/stylesheets/hyrax/_card.scss +4 -0
- data/app/assets/stylesheets/hyrax/_catalog.scss +21 -0
- data/app/assets/stylesheets/hyrax/_collections.scss +1 -1
- data/app/assets/stylesheets/hyrax/_facets.scss +15 -3
- data/app/assets/stylesheets/hyrax/_featured.scss +4 -0
- data/app/assets/stylesheets/hyrax/_form.scss +4 -0
- data/app/assets/stylesheets/hyrax/_forms.scss +2 -1
- data/app/assets/stylesheets/hyrax/_nestable.scss +9 -8
- data/app/assets/stylesheets/hyrax/_select_work_type.scss +12 -0
- data/app/assets/stylesheets/hyrax/_styles.scss +4 -0
- data/app/assets/stylesheets/hyrax/_work-show.scss +3 -0
- data/app/controllers/concerns/hyrax/singular_subresource_controller.rb +7 -2
- data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +11 -2
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +9 -2
- data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +2 -2
- data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +7 -8
- data/app/controllers/hyrax/dashboard/collections_controller.rb +2 -1
- data/app/controllers/hyrax/downloads_controller.rb +24 -3
- data/app/controllers/hyrax/file_sets_controller.rb +32 -6
- data/app/controllers/hyrax/my/works_controller.rb +20 -0
- data/app/controllers/hyrax/stats_controller.rb +1 -1
- data/app/controllers/hyrax/uploads_controller.rb +28 -2
- data/app/forms/hyrax/forms/admin/appearance.rb +1 -1
- data/app/forms/hyrax/forms/admin/collection_type_form.rb +1 -7
- data/app/forms/hyrax/forms/pcdm_collection_form.rb +9 -0
- data/app/forms/hyrax/forms/work_embargo_form.rb +6 -0
- data/app/forms/hyrax/forms/work_lease_form.rb +6 -0
- data/app/indexers/concerns/hyrax/location_indexer.rb +2 -2
- data/app/indexers/hyrax/indexers/file_set_indexer.rb +4 -0
- data/app/indexers/hyrax/indexers/resource_indexer.rb +1 -0
- data/app/indexers/hyrax/valkyrie_indexer.rb +3 -5
- data/app/jobs/migrate_files_to_valkyrie_job.rb +109 -0
- data/app/jobs/migrate_resources_job.rb +34 -0
- data/app/jobs/valkyrie_create_derivatives_job.rb +2 -1
- data/app/models/admin_set.rb +1 -0
- data/app/models/concerns/hyrax/ar_resource.rb +104 -0
- data/app/models/concerns/hyrax/solr_document/ordered_members.rb +2 -1
- data/app/models/concerns/hyrax/solr_document_behavior.rb +13 -2
- data/app/models/concerns/hyrax/valkyrie_lazy_migration.rb +82 -0
- data/app/models/file_download_stat.rb +1 -1
- data/app/models/file_view_stat.rb +1 -1
- data/app/models/hyrax/collection_type.rb +12 -4
- data/app/models/hyrax/file_metadata.rb +19 -0
- data/app/models/hyrax/file_set.rb +25 -0
- data/app/models/hyrax/model_registry.rb +2 -3
- data/app/models/hyrax/resource.rb +5 -0
- data/app/models/hyrax/statistic.rb +12 -37
- data/app/presenters/hyrax/file_set_presenter.rb +2 -1
- data/app/presenters/hyrax/file_usage.rb +3 -3
- data/app/presenters/hyrax/iiif_manifest_presenter.rb +2 -1
- data/app/presenters/hyrax/member_presenter_factory.rb +7 -1
- data/app/presenters/hyrax/menu_presenter.rb +1 -1
- data/app/presenters/hyrax/stats_usage_presenter.rb +2 -1
- data/app/presenters/hyrax/work_show_presenter.rb +13 -17
- data/app/presenters/hyrax/work_usage.rb +5 -2
- data/app/search_builders/hyrax/expired_embargo_search_builder.rb +7 -1
- data/app/search_builders/hyrax/expired_lease_search_builder.rb +7 -1
- data/app/search_builders/hyrax/filter_by_type.rb +1 -3
- data/app/search_builders/hyrax/valkyrie_abstract_type_relation.rb +7 -2
- data/app/services/hyrax/access_control_list.rb +1 -1
- data/app/services/hyrax/admin_set_create_service.rb +16 -5
- data/app/services/hyrax/admin_set_service.rb +2 -1
- data/app/services/hyrax/analytics/ga4/base.rb +96 -0
- data/app/services/hyrax/analytics/ga4/events.rb +25 -0
- data/app/services/hyrax/analytics/ga4/events_daily.rb +36 -0
- data/app/services/hyrax/analytics/ga4/visits.rb +33 -0
- data/app/services/hyrax/analytics/ga4/visits_daily.rb +24 -0
- data/app/services/hyrax/analytics/ga4.rb +204 -0
- data/app/services/hyrax/analytics/google.rb +16 -2
- data/app/services/hyrax/analytics/matomo.rb +16 -3
- data/app/services/hyrax/analytics/results.rb +6 -0
- data/app/services/hyrax/custom_queries/find_access_control.rb +1 -1
- data/app/services/hyrax/custom_queries/find_by_date_range.rb +6 -23
- data/app/services/hyrax/custom_queries/find_collections_by_type.rb +2 -2
- data/app/services/hyrax/custom_queries/find_count_by.rb +3 -31
- data/app/services/hyrax/custom_queries/find_file_metadata.rb +2 -2
- data/app/services/hyrax/custom_queries/find_models_by_access.rb +5 -27
- data/app/services/hyrax/embargo_manager.rb +2 -1
- data/app/services/hyrax/listeners/file_listener.rb +2 -2
- data/app/services/hyrax/lock_manager.rb +6 -6
- data/app/services/hyrax/lockable.rb +4 -3
- data/app/services/hyrax/simple_schema_loader.rb +1 -1
- data/app/services/hyrax/solr_service.rb +22 -8
- data/app/services/hyrax/statistics/query_service.rb +1 -1
- data/app/services/hyrax/statistics/works/over_time.rb +1 -1
- data/app/services/hyrax/thumbnail_path_service.rb +2 -0
- data/app/services/hyrax/user_stat_importer.rb +5 -5
- data/app/services/hyrax/valkyrie_upload.rb +9 -7
- data/app/services/hyrax/versioning_service.rb +10 -2
- data/app/services/hyrax/work_query_service.rb +2 -2
- data/app/services/migrate_resource_service.rb +55 -0
- data/app/views/_controls.html.erb +5 -5
- data/app/views/_masthead.html.erb +1 -1
- data/app/views/catalog/_search_form.html.erb +9 -16
- data/app/views/catalog/_thumbnail_list_collection.html.erb +1 -1
- data/app/views/catalog/_thumbnail_list_default.html.erb +2 -2
- data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +4 -4
- data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +1 -1
- data/app/views/hyrax/admin/collection_types/_form.html.erb +4 -4
- data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
- data/app/views/hyrax/admin/features/index.html.erb +1 -1
- data/app/views/hyrax/base/_file_manager_actions.html.erb +1 -1
- data/app/views/hyrax/base/_file_manager_member.html.erb +7 -4
- data/app/views/hyrax/base/_file_manager_thumbnail.html.erb +1 -1
- data/app/views/hyrax/base/_form_files.html.erb +1 -1
- data/app/views/hyrax/base/_form_member_of_collections.html.erb +4 -0
- data/app/views/hyrax/base/_show_actions.html.erb +7 -8
- data/app/views/hyrax/base/_work_button_row.html.erb +1 -1
- data/app/views/hyrax/batch_select/_add_button.html.erb +1 -1
- data/app/views/hyrax/content_blocks/_form.html.erb +3 -3
- data/app/views/hyrax/dashboard/_sidebar.html.erb +1 -1
- data/app/views/hyrax/dashboard/_user_activity.html.erb +2 -2
- data/app/views/hyrax/dashboard/collections/_form.html.erb +4 -4
- data/app/views/hyrax/dashboard/collections/_form_share.html.erb +6 -4
- data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +1 -1
- data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
- data/app/views/hyrax/dashboard/show_admin.html.erb +18 -19
- data/app/views/hyrax/dashboard/sidebar/_activity.html.erb +1 -1
- data/app/views/hyrax/embargoes/_list_expired_active_embargoes.html.erb +7 -7
- data/app/views/hyrax/file_sets/_actions.html.erb +9 -1
- data/app/views/hyrax/file_sets/_permission_form.html.erb +4 -2
- data/app/views/hyrax/file_sets/_show_actions.html.erb +1 -1
- data/app/views/hyrax/homepage/_featured.html.erb +1 -1
- data/app/views/hyrax/homepage/_recent_document.html.erb +2 -2
- data/app/views/hyrax/leases/_list_expired_active_leases.html.erb +6 -6
- data/app/views/hyrax/my/collections/_list_collections.html.erb +1 -1
- data/app/views/hyrax/my/collections/_tabs.html.erb +1 -1
- data/app/views/hyrax/pages/_form.html.erb +8 -8
- data/app/views/hyrax/transfers/_received.html.erb +1 -1
- data/app/views/hyrax/uploads/create.json.jbuilder +2 -2
- data/app/views/hyrax/users/_activity_log.html.erb +15 -9
- data/app/views/hyrax/users/_user_row.html.erb +6 -3
- data/app/views/hyrax/users/_vitals.html.erb +3 -2
- data/app/views/layouts/_head_tag_content.html.erb +2 -0
- data/app/views/shared/_appearance_styles.html.erb +5 -1
- data/app/views/shared/_ga4.html.erb +11 -0
- data/app/views/shared/_select_work_type_modal.html.erb +10 -1
- data/bin/db-migrate-seed.sh +3 -3
- data/bin/dev-entrypoint.sh +7 -2
- data/bin/{db-wait.sh → service-wait.sh} +1 -1
- data/bin/worker-entrypoint.sh +8 -0
- data/chart/hyrax/templates/deployment-worker.yaml +2 -2
- data/config/locales/hyrax.en.yml +4 -2
- data/config/metadata/basic_metadata.yaml +20 -0
- data/config/metadata/hyrax_internal_metadata.yaml +1 -1
- data/docker-compose-dassie.yml +167 -0
- data/docker-compose-koppie.yml +21 -36
- data/docker-compose-sirenia.yml +50 -44
- data/docker-compose.yml +2 -183
- data/documentation/developing-your-hyrax-based-app.md +2 -2
- data/hyrax.gemspec +5 -4
- data/lib/freyja/custom_query_container.rb +5 -0
- data/lib/freyja/metadata_adapter.rb +32 -0
- data/lib/freyja/persister.rb +42 -0
- data/lib/freyja/query_service.rb +20 -0
- data/lib/freyja/resource_factory.rb +8 -0
- data/lib/freyja.rb +14 -0
- data/lib/frigg/custom_query_container.rb +5 -0
- data/lib/frigg/metadata_adapter.rb +22 -0
- data/lib/frigg/persister.rb +33 -0
- data/lib/frigg/query_service.rb +15 -0
- data/lib/frigg.rb +13 -0
- data/lib/generators/hyrax/install_generator.rb +5 -0
- data/lib/generators/hyrax/templates/config/analytics.yml +6 -1
- data/lib/generators/hyrax/templates/config/initializers/1_valkyrie.rb +6 -2
- data/lib/generators/hyrax/templates/config/valkyrie_index.yml +1 -1
- data/lib/goddess/custom_query_container.rb +71 -0
- data/lib/goddess/metadata.rb +13 -0
- data/lib/goddess/query.rb +176 -0
- data/lib/hyrax/configuration.rb +83 -0
- data/lib/hyrax/engine.rb +2 -0
- data/lib/hyrax/form_fields.rb +1 -3
- data/lib/hyrax/name.rb +5 -0
- data/lib/hyrax/rubocop/custom_cops.rb +30 -0
- data/lib/hyrax/specs/capybara.rb +10 -6
- data/lib/hyrax/specs/shared_specs/factories/admin_sets.rb +2 -0
- data/lib/hyrax/specs/shared_specs/factories/hyrax_embargo.rb +4 -0
- data/lib/hyrax/specs/shared_specs/factories/hyrax_lease.rb +4 -0
- data/lib/hyrax/specs/shared_specs/factories/hyrax_work.rb +16 -2
- data/lib/hyrax/specs/shared_specs/hydra_works.rb +1 -1
- data/lib/hyrax/transactions/admin_set_destroy.rb +2 -1
- data/lib/hyrax/transactions/collection_destroy.rb +2 -1
- data/lib/hyrax/transactions/container.rb +9 -0
- data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
- data/lib/hyrax/transactions/steps/delete_permission_template.rb +30 -0
- data/lib/hyrax/transactions/steps/delete_resource.rb +1 -1
- data/lib/hyrax/transactions/steps/save_collection_logo.rb +2 -1
- data/lib/hyrax/valkyrie_can_can_adapter.rb +8 -1
- data/lib/hyrax/version.rb +1 -1
- data/lib/wings/active_fedora_converter.rb +13 -5
- data/lib/wings/converter_value_mapper.rb +1 -0
- data/lib/wings/services/custom_queries/find_collections_by_type.rb +2 -1
- data/lib/wings/services/custom_queries/find_file_metadata.rb +2 -2
- data/lib/wings/setup.rb +12 -3
- data/lib/wings/transformer_value_mapper.rb +5 -1
- data/lib/wings/valkyrie/persister.rb +3 -1
- data/template.rb +1 -1
- metadata +77 -19
- data/.koppie/scripts/db-migrate-seed.sh +0 -9
- data/.koppie/scripts/entrypoint.sh +0 -10
@@ -11,15 +11,38 @@ module Hyrax
|
|
11
11
|
:original_file
|
12
12
|
end
|
13
13
|
|
14
|
+
# We want to alias the show method for a later use with #show_active_fedora;
|
15
|
+
# because we're adding quite a bit of logic and need a good alias. Why the
|
16
|
+
# alias? Because we were using `super' for the show method and that just
|
17
|
+
# doesn't quite work with all of the antics we're performing.
|
18
|
+
alias hydra_show_active_fedora_file show
|
19
|
+
|
14
20
|
# Render the 404 page if the file doesn't exist.
|
15
21
|
# Otherwise renders the file.
|
16
22
|
def show
|
23
|
+
# We will use the thumbnail from our file system first, if one exists
|
24
|
+
# Otherwise we will fallback to Valkyrie, then the default implementations
|
25
|
+
use = params.fetch(:file, :original_file).to_sym
|
26
|
+
if use == :thumbnail
|
27
|
+
thumbnail = Hyrax::DerivativePath.derivative_path_for_reference(params[:id], 'thumbnail')
|
28
|
+
if thumbnail.present? && File.exist?(thumbnail)
|
29
|
+
@file = thumbnail
|
30
|
+
return send_local_content
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
17
34
|
return show_valkyrie if Hyrax.config.use_valkyrie?
|
18
35
|
|
36
|
+
show_active_fedora
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def show_active_fedora
|
19
42
|
case file
|
20
43
|
when ActiveFedora::File
|
21
44
|
# For original files that are stored in fedora
|
22
|
-
|
45
|
+
hydra_show_active_fedora_file
|
23
46
|
when String
|
24
47
|
# For derivatives stored on the local file system
|
25
48
|
send_local_content
|
@@ -28,8 +51,6 @@ module Hyrax
|
|
28
51
|
end
|
29
52
|
end
|
30
53
|
|
31
|
-
private
|
32
|
-
|
33
54
|
# Override the Hydra::Controller::DownloadBehavior#content_options so that
|
34
55
|
# we have an attachement rather than 'inline'
|
35
56
|
def content_options
|
@@ -8,7 +8,7 @@ module Hyrax
|
|
8
8
|
include Hyrax::Breadcrumbs
|
9
9
|
|
10
10
|
before_action :authenticate_user!, except: [:show, :citation, :stats]
|
11
|
-
load_and_authorize_resource class:
|
11
|
+
load_and_authorize_resource class: Hyrax.config.file_set_class
|
12
12
|
before_action :build_breadcrumbs, only: [:show, :edit, :stats]
|
13
13
|
before_action do
|
14
14
|
blacklight_config.track_search_session = false
|
@@ -94,7 +94,7 @@ module Hyrax
|
|
94
94
|
# @api public
|
95
95
|
def delete(file_set:)
|
96
96
|
case file_set
|
97
|
-
when
|
97
|
+
when Hyrax::Resource
|
98
98
|
transactions['file_set.destroy']
|
99
99
|
.with_step_args('file_set.remove_from_work' => { user: current_user },
|
100
100
|
'file_set.delete' => { user: current_user })
|
@@ -123,20 +123,46 @@ module Hyrax
|
|
123
123
|
def valkyrie_update_metadata
|
124
124
|
change_set = Hyrax::Forms::ResourceForm.for(resource: file_set)
|
125
125
|
|
126
|
+
attributes = coerce_valkyrie_params
|
127
|
+
|
128
|
+
# TODO: We are not performing any error checks. So that's something to
|
129
|
+
# correct.
|
126
130
|
result =
|
127
131
|
change_set.validate(attributes) &&
|
128
132
|
transactions['change_set.update_file_set']
|
129
133
|
.with_step_args(
|
130
|
-
|
131
|
-
|
134
|
+
'file_set.save_acl' => { permissions_params: change_set.input_params["permissions"] }
|
135
|
+
)
|
132
136
|
.call(change_set).value_or { false }
|
133
137
|
@file_set = result if result
|
134
138
|
end
|
135
139
|
|
140
|
+
def coerce_valkyrie_params
|
141
|
+
attrs = attributes
|
142
|
+
# The HTML form might not submit the required data structure for reform;
|
143
|
+
# namely instead of a hash with positional arguments for nested attributes
|
144
|
+
# of a collection, it is an array. So we conditionally coerce that Array
|
145
|
+
# to a Hash.
|
146
|
+
|
147
|
+
# TODO: Do we need to concern ourself with embargo_attributes and
|
148
|
+
# lease_attributes? My suspicion is that since these are singular (for
|
149
|
+
# now), we don't. But it's a quick add.
|
150
|
+
[:permissions].each do |name|
|
151
|
+
next unless attrs["#{name}_attributes"].is_a?(Array)
|
152
|
+
new_perm_attrs = {}
|
153
|
+
attrs["#{name}_attributes"].each_with_index do |el, i|
|
154
|
+
new_perm_attrs[i] = el
|
155
|
+
end
|
156
|
+
|
157
|
+
attrs["#{name}_attributes"] = new_perm_attrs
|
158
|
+
end
|
159
|
+
attrs
|
160
|
+
end
|
161
|
+
|
136
162
|
def parent(file_set: curation_concern)
|
137
163
|
@parent ||=
|
138
164
|
case file_set
|
139
|
-
when Hyrax::
|
165
|
+
when Hyrax::Resource
|
140
166
|
# TODO: Add Hyrax::FileSet#parent method
|
141
167
|
Hyrax.query_service.find_parents(resource: file_set).first
|
142
168
|
else
|
@@ -145,7 +171,7 @@ module Hyrax
|
|
145
171
|
end
|
146
172
|
|
147
173
|
def attempt_update
|
148
|
-
return attempt_update_valkyrie if
|
174
|
+
return attempt_update_valkyrie if curation_concern.is_a?(Hyrax::Resource)
|
149
175
|
if wants_to_revert?
|
150
176
|
actor.revert_content(params[:revision])
|
151
177
|
elsif params.key?(:file_set)
|
@@ -24,6 +24,7 @@ module Hyrax
|
|
24
24
|
add_breadcrumb t(:'hyrax.admin.sidebar.works'), hyrax.my_works_path
|
25
25
|
managed_works_count
|
26
26
|
@create_work_presenter = create_work_presenter_class.new(current_user)
|
27
|
+
@admin_sets_for_select = admin_sets_for_select
|
27
28
|
super
|
28
29
|
end
|
29
30
|
|
@@ -47,6 +48,25 @@ module Hyrax
|
|
47
48
|
def managed_works_count
|
48
49
|
@managed_works_count = Hyrax::Works::ManagedWorksService.managed_works_count(scope: self)
|
49
50
|
end
|
51
|
+
|
52
|
+
def admin_sets_for_select
|
53
|
+
source_ids = Hyrax::Collections::PermissionsService.source_ids_for_deposit(ability: current_ability, source_type: 'admin_set')
|
54
|
+
|
55
|
+
admin_sets_list = Hyrax.query_service.find_many_by_ids(ids: source_ids).map do |source|
|
56
|
+
[source.title.first, source.id]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sorts the default admin set to be first, then the rest by title.
|
60
|
+
admin_sets_list.sort do |a, b|
|
61
|
+
if Hyrax::AdminSetCreateService.default_admin_set?(id: a[1])
|
62
|
+
-1
|
63
|
+
elsif Hyrax::AdminSetCreateService.default_admin_set?(id: b[1])
|
64
|
+
1
|
65
|
+
else
|
66
|
+
a[0] <=> b[0]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
50
70
|
end
|
51
71
|
end
|
52
72
|
end
|
@@ -27,7 +27,7 @@ module Hyrax
|
|
27
27
|
when 'file'
|
28
28
|
add_breadcrumb I18n.t("hyrax.file_set.browse_view"), main_app.hyrax_file_set_path(params["id"])
|
29
29
|
when 'work'
|
30
|
-
add_breadcrumb @work.
|
30
|
+
add_breadcrumb @work.title.first, main_app.polymorphic_path(@work)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -4,8 +4,12 @@ module Hyrax
|
|
4
4
|
load_and_authorize_resource class: Hyrax::UploadedFile
|
5
5
|
|
6
6
|
def create
|
7
|
-
|
8
|
-
|
7
|
+
if params[:id].blank?
|
8
|
+
@upload.attributes = { file: params[:files].first,
|
9
|
+
user: current_user }
|
10
|
+
else
|
11
|
+
upload_with_chunking
|
12
|
+
end
|
9
13
|
@upload.save!
|
10
14
|
end
|
11
15
|
|
@@ -13,5 +17,27 @@ module Hyrax
|
|
13
17
|
@upload.destroy
|
14
18
|
head :no_content
|
15
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def upload_with_chunking
|
24
|
+
@upload = Hyrax::UploadedFile.find(params[:id])
|
25
|
+
unpersisted_upload = Hyrax::UploadedFile.new(file: params[:files].first, user: current_user)
|
26
|
+
|
27
|
+
# Check if CONTENT-RANGE header is present
|
28
|
+
content_range = request.headers['CONTENT-RANGE']
|
29
|
+
return @upload.file = unpersisted_upload.file if content_range.nil?
|
30
|
+
|
31
|
+
# deal with chunks
|
32
|
+
current_size = @upload.file.size
|
33
|
+
begin_of_chunk = content_range[/\ (.*?)-/, 1].to_i # "bytes 100-999999/1973660678" will return '100'
|
34
|
+
|
35
|
+
# Add the following chunk to the incomplete upload
|
36
|
+
if @upload.file.present? && begin_of_chunk == current_size
|
37
|
+
File.open(@upload.file.path, "ab") { |f| f.write(params[:files].first.read) }
|
38
|
+
else
|
39
|
+
@upload.file = unpersisted_upload.file
|
40
|
+
end
|
41
|
+
end
|
16
42
|
end
|
17
43
|
end
|
@@ -10,7 +10,7 @@ module Hyrax
|
|
10
10
|
delegate :title, :description, :brandable, :discoverable, :nestable, :sharable, :share_applies_to_new_works,
|
11
11
|
:require_membership, :allow_multiple_membership, :assigns_workflow,
|
12
12
|
:assigns_visibility, :id, :collection_type_participants, :persisted?,
|
13
|
-
:admin_set?, :user_collection?, :badge_color, to: :collection_type
|
13
|
+
:admin_set?, :user_collection?, :badge_color, :collections?, to: :collection_type
|
14
14
|
|
15
15
|
##
|
16
16
|
# @return [Boolean]
|
@@ -23,12 +23,6 @@ module Hyrax
|
|
23
23
|
def share_options_disabled?
|
24
24
|
all_settings_disabled? || !sharable
|
25
25
|
end
|
26
|
-
|
27
|
-
##
|
28
|
-
# @return [Boolean]
|
29
|
-
def collections?
|
30
|
-
collection_type.collections.any?
|
31
|
-
end
|
32
26
|
end
|
33
27
|
end
|
34
28
|
end
|
@@ -81,6 +81,15 @@ module Hyrax
|
|
81
81
|
secondary_terms.any?
|
82
82
|
end
|
83
83
|
|
84
|
+
##
|
85
|
+
# This feature is not supported in Valkyrie collections and should be removed as part of #5764
|
86
|
+
# However, the depreciated method is still needed for some specs
|
87
|
+
# @return [] always empty.
|
88
|
+
def select_files
|
89
|
+
Deprecation.warn "`Hyrax::PcdmCollection` does not currently support thumbnail_id. Collection thumbnails need to be redesigned as part of issue #5764"
|
90
|
+
[]
|
91
|
+
end
|
92
|
+
|
84
93
|
private
|
85
94
|
|
86
95
|
def _form_field_definitions
|
@@ -6,7 +6,7 @@ module Hyrax
|
|
6
6
|
module LocationIndexer
|
7
7
|
def to_solr
|
8
8
|
super.tap do |index_document|
|
9
|
-
index_document[:based_near_label_tesim] = based_near_label_lookup(resource.based_near) if resource.respond_to? :based_near
|
9
|
+
index_document[:based_near_label_tesim] = index_document[:based_near_label_sim] = based_near_label_lookup(resource.based_near) if resource.respond_to? :based_near
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -14,7 +14,7 @@ module Hyrax
|
|
14
14
|
|
15
15
|
def based_near_label_lookup(locations)
|
16
16
|
locations.map do |loc|
|
17
|
-
location_service.full_label(loc)
|
17
|
+
location_service.full_label(loc) if loc.present?
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -101,6 +101,10 @@ module Hyrax
|
|
101
101
|
|
102
102
|
# attributes set by fits for video
|
103
103
|
solr_doc['aspect_ratio_tesim'] = file_metadata.aspect_ratio if file_metadata.aspect_ratio.present?
|
104
|
+
|
105
|
+
# support for derivatives download
|
106
|
+
derivatives = resource.extensions_and_mime_types
|
107
|
+
solr_doc['extensions_and_mime_types_ssm'] = derivatives.to_json if derivatives.present?
|
104
108
|
end
|
105
109
|
end
|
106
110
|
|
@@ -47,6 +47,7 @@ module Hyrax
|
|
47
47
|
"system_modified_dtsi": resource.updated_at,
|
48
48
|
"has_model_ssim": resource.to_rdf_representation,
|
49
49
|
"human_readable_type_tesim": resource.human_readable_type,
|
50
|
+
"human_readable_type_sim": resource.human_readable_type,
|
50
51
|
"alternate_ids_sim": resource.alternate_ids.map(&:to_s)
|
51
52
|
}.with_indifferent_access
|
52
53
|
end
|
@@ -9,11 +9,9 @@ module Hyrax
|
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Hyrax::Indexers::ResourceIndexer.for(*args, **kwargs)
|
16
|
-
end
|
12
|
+
def self.for(*args, **kwargs)
|
13
|
+
Deprecation.warn "`Hyrax::ValkyrieIndexer.for` is deprecated. Use `Hyrax::Indexers::ResourceIndexer.for` instead."
|
14
|
+
Hyrax::Indexers::ResourceIndexer.for(*args, **kwargs)
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
##
|
2
|
+
# Responsible for conditionally enqueuing the file and thumbnail migration
|
3
|
+
# logic of an ActiveFedora object.
|
4
|
+
class MigrateFilesToValkyrieJob < Hyrax::ApplicationJob
|
5
|
+
##
|
6
|
+
#
|
7
|
+
# @param resource [Hyrax::FileSet]
|
8
|
+
def perform(resource)
|
9
|
+
migrate_derivatives!(resource:)
|
10
|
+
# need to reload file_set to get the derivative ids
|
11
|
+
resource = Hyrax.query_service.find_by(id: resource.id)
|
12
|
+
migrate_files!(resource: resource)
|
13
|
+
end
|
14
|
+
|
15
|
+
def attribute_mapping
|
16
|
+
return @attribute_mapping if @attribute_mapping
|
17
|
+
@attribute_mapping = %w[
|
18
|
+
aspect_ratio bit_depth bit_rate byte_order capture_device channels character_count character_set
|
19
|
+
checksum color_map color_space compression creator data_format duration exif_version file_title
|
20
|
+
fits_version format_label frame_rate gps_timestamp graphics_count height image_producer language
|
21
|
+
latitude line_count longitude markup_basis markup_language offset orientation page_count
|
22
|
+
paragraph_count profile_name profile_version recorded_size sample_rate scanning_software
|
23
|
+
table_count well_formed width word_count ].inject({}) { |j, i| j[i] = i; j}
|
24
|
+
@attribute_mapping['recorded_size'] = 'file_size'
|
25
|
+
@attribute_mapping['channels'] = 'alpha_channels'
|
26
|
+
@attribute_mapping['checksum'] = 'original_checksum'
|
27
|
+
@attribute_mapping
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def migrate_derivatives!(resource:)
|
33
|
+
# @todo should we trigger a job if the member is a child work?
|
34
|
+
paths = Hyrax::DerivativePath.derivatives_for_reference(resource)
|
35
|
+
paths.each do |path|
|
36
|
+
container = container_for(path)
|
37
|
+
mime_type = Marcel::MimeType.for(extension: File.extname(path))
|
38
|
+
directives = { url: path, container: container, mime_type: mime_type }
|
39
|
+
File.open(path, 'rb') do |content|
|
40
|
+
Hyrax::ValkyriePersistDerivatives.call(content, directives)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Move the ActiveFedora files out of ActiveFedora's domain and into the
|
47
|
+
# configured {Hyrax.storage_adapter}'s domain.
|
48
|
+
def migrate_files!(resource:)
|
49
|
+
return unless resource.respond_to?(:file_ids)
|
50
|
+
|
51
|
+
files = Hyrax.custom_queries.find_many_file_metadata_by_ids(ids: resource.file_ids)
|
52
|
+
files.each do |file|
|
53
|
+
# If it doesn't start with fedora, we've likely already migrated it.
|
54
|
+
next unless /^fedora:/.match?(file.file_identifier.to_s)
|
55
|
+
resource.file_ids.delete(file.id)
|
56
|
+
|
57
|
+
Tempfile.create do |tempfile|
|
58
|
+
tempfile.binmode
|
59
|
+
tempfile.write(URI.open(file.file_identifier.to_s.gsub("fedora:", "http:")).read)
|
60
|
+
tempfile.rewind
|
61
|
+
|
62
|
+
# valkyrie_file = Hyrax.storage_adapter.upload(resource: resource, file: tempfile, original_filename: file.original_filename)
|
63
|
+
valkyrie_file = Hyrax::ValkyrieUpload.file(
|
64
|
+
filename: resource.label,
|
65
|
+
file_set: resource,
|
66
|
+
io: tempfile,
|
67
|
+
use: file.pcdm_use.select {|use| Hyrax::FileMetadata::Use.use_list.include?(use)},
|
68
|
+
user: User.find_or_initialize_by(User.user_key_field => resource.depositor),
|
69
|
+
mime_type: file.mime_type,
|
70
|
+
skip_derivatives: true
|
71
|
+
)
|
72
|
+
valkyrie_file = copy_attributes(valkyrie_file:, original_file: file)
|
73
|
+
Hyrax.persister.save(resource: valkyrie_file)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
# reindex the file set after migrating files to include characterization info
|
77
|
+
Hyrax.index_adapter.save(resource: resource)
|
78
|
+
end
|
79
|
+
|
80
|
+
def copy_attributes(valkyrie_file:, original_file:)
|
81
|
+
attribute_mapping.each do |k, v|
|
82
|
+
valkyrie_file.set_value(k, original_file.send(v))
|
83
|
+
end
|
84
|
+
# Special case as this property isn't in the characterization proxy
|
85
|
+
valkyrie_file.set_value('alternate_ids', original_file.alternate_ids)
|
86
|
+
valkyrie_file
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Map from the file name used for the derivative to a valid option for
|
91
|
+
# container that ValkyriePersistDerivatives can convert into a
|
92
|
+
# Hyrax::Metadata::Use
|
93
|
+
#
|
94
|
+
# @param filename [String] the name of the derivative file: i.e. 'x-thumbnail.jpg'
|
95
|
+
# @return [String]
|
96
|
+
def container_for(filename)
|
97
|
+
# we want the portion between the '-' and the '.'
|
98
|
+
file_blob = File.basename(filename, '.*').split('-').last
|
99
|
+
|
100
|
+
case file_blob
|
101
|
+
when 'thumbnail'
|
102
|
+
'thumbnail_image'
|
103
|
+
when 'txt', 'json', 'xml'
|
104
|
+
'extracted_text'
|
105
|
+
else
|
106
|
+
'service_file'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# migrates models from AF to valkyrie
|
4
|
+
class MigrateResourcesJob < ApplicationJob
|
5
|
+
attr_writer :errors
|
6
|
+
# input [Array>>String] Array of ActiveFedora model names to migrate to valkyrie objects
|
7
|
+
# defaults to AdminSet & Collection models if empty
|
8
|
+
def perform(ids: [], models: ['AdminSet', 'Collection'])
|
9
|
+
if ids.blank?
|
10
|
+
models.each do |model|
|
11
|
+
model.constantize.find_each do |item|
|
12
|
+
migrate(item.id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
else
|
16
|
+
ids.each do |id|
|
17
|
+
migrate(id)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
raise errors.inspect if errors.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def errors
|
24
|
+
@errors ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def migrate(id)
|
28
|
+
resource = Hyrax.query_service.find_by(id: id)
|
29
|
+
return unless resource.wings? # this resource has already been converted
|
30
|
+
result = MigrateResourceService.new(resource: resource).call
|
31
|
+
errors << result unless result.success?
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
@@ -16,8 +16,9 @@ class ValkyrieCreateDerivativesJob < Hyrax::ApplicationJob
|
|
16
16
|
|
17
17
|
def reindex_parent(file_set_id)
|
18
18
|
file_set = Hyrax.query_service.find_by(id: file_set_id)
|
19
|
+
return unless file_set
|
19
20
|
parent = Hyrax.custom_queries.find_parent_work(resource: file_set)
|
20
|
-
return unless parent
|
21
|
+
return unless parent&.thumbnail_id == file_set.id
|
21
22
|
Hyrax.logger.debug { "Reindexing #{parent.id} due to creation of thumbnail derivatives." }
|
22
23
|
Hyrax.index_adapter.save(resource: parent)
|
23
24
|
end
|
data/app/models/admin_set.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
# @see Hyrax::DefaultAdminSetActor
|
18
18
|
# @see Hyrax::ApplyPermissionTemplateActor
|
19
19
|
class AdminSet < ActiveFedora::Base
|
20
|
+
include Hydra::PCDM::CollectionBehavior
|
20
21
|
include Hydra::AccessControls::Permissions
|
21
22
|
include Hyrax::Noid
|
22
23
|
include Hyrax::HumanReadableType
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hyrax
|
3
|
+
# An optional model to bring active record like accessors to your Valkyrie resources. This
|
4
|
+
# is simply for simplicity in the console and backward compatibility.
|
5
|
+
module ArResource
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
##
|
10
|
+
# find a Valkyrie object by its primary identifyer.
|
11
|
+
#
|
12
|
+
# @param id [String]
|
13
|
+
# @return [Valkyrie::Resource]
|
14
|
+
def find(id, query_service: Hyrax.query_service)
|
15
|
+
query_service.find_by(id: id)
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# find and item by an arbitrary keyword arguements if and only if that property is supported
|
20
|
+
# by the current query_service. custom queries are often limited so be aware that this does
|
21
|
+
# support all properties of an object.
|
22
|
+
#
|
23
|
+
# @params query_service [Valkyrie::QueryService] (optional) the query service to use
|
24
|
+
# @param [Hash] opts the options to send to the query service. Can only be one argument.
|
25
|
+
# this argument will be converted to the query in the form of find_by_#{opts.keys.first}
|
26
|
+
# @return [Valkyrie::Resource]
|
27
|
+
def find_by(query_service: Hyrax.query_service, **opts)
|
28
|
+
if opts.key?(:id)
|
29
|
+
find(opts[:id], query_service: query_service)
|
30
|
+
else
|
31
|
+
method_name = "find_by_#{opts.keys.first}"
|
32
|
+
value = opts[opts.values.first]
|
33
|
+
return query_service.send(method_name, value) if query_service.respond_to?(method_name)
|
34
|
+
query_service.custom_query.send(method_name, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
rescue Valkyrie::Persistence::ObjectNotFoundError
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# @param query_service [#find_parents]
|
44
|
+
#
|
45
|
+
# @return [NilClass] when this object does not have a parent.
|
46
|
+
# @return [Valkyrie::Resource] when this object has at least one parent.
|
47
|
+
def parent(query_service: Hyrax.query_service)
|
48
|
+
query_service.find_parents(resource: self).first
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# This will persist the object to the repository. Not a complete transaction set up, but will
|
53
|
+
# index and notify listeners of metadata update
|
54
|
+
#
|
55
|
+
# @param [Hyrax::Persister] Valkyrie persister (optional) will default to Hyrax.persister
|
56
|
+
# @param [Hyrax::IndexAdapter] Valkyrie index adapter (optional) will default to Hyrax.index_adapter
|
57
|
+
# @param [User] user the user to record the event for. Will not set depositor yet
|
58
|
+
# @return [Valkyrie::Resource]
|
59
|
+
def save(persister: Hyrax.persister, index_adapter: Hyrax.index_adapter, user: ::User.system_user)
|
60
|
+
is_new = new_record
|
61
|
+
result = persister.save(resource: self)
|
62
|
+
return nil unless result.persisted?
|
63
|
+
index_adapter.save(resource: result)
|
64
|
+
if result.collection?
|
65
|
+
Hyrax.publisher.publish('collection.metadata.updated', collection: result, user: user)
|
66
|
+
else
|
67
|
+
Hyrax.publisher.publish('object.deposited', object: result, user: user) if is_new
|
68
|
+
Hyrax.publisher.publish('object.metadata.updated', object: result, user: user)
|
69
|
+
end
|
70
|
+
# TODO: do we need to replace the properties here?
|
71
|
+
self.new_record = false
|
72
|
+
self.id = result.id
|
73
|
+
|
74
|
+
result
|
75
|
+
end
|
76
|
+
alias create save
|
77
|
+
alias update save
|
78
|
+
|
79
|
+
def save!(**opts)
|
80
|
+
raise Valkyrie::Persistence::ObjectNotFoundError unless save(**opts)
|
81
|
+
end
|
82
|
+
alias create! save!
|
83
|
+
alias update! save!
|
84
|
+
|
85
|
+
##
|
86
|
+
# This will delete the resource and publish its delete event
|
87
|
+
#
|
88
|
+
# @param [Hyrax::Persister] Valkyrie persister (optional) will default to Hyrax.persister
|
89
|
+
# @param [Hyrax::IndexAdapter] Valkyrie index adapter (optional) will default to Hyrax.index_adapter
|
90
|
+
# @param [User] user the user to record the event for. Will not set depositor yet
|
91
|
+
# @return [Boolean]
|
92
|
+
def destroy(persister: Hyrax.persister, index_adapter: Hyrax.index_adapter, user: ::User.system_user)
|
93
|
+
return false unless persisted?
|
94
|
+
persister.delete(resource: self)
|
95
|
+
index_adapter.delete(resource: self)
|
96
|
+
Hyrax.publisher.publish('object.deleted', object: self, user: user)
|
97
|
+
true
|
98
|
+
end
|
99
|
+
|
100
|
+
def destroy!(**opts)
|
101
|
+
raise Valkyrie::Persistence::ObjectNotFoundError unless destroy(**opts)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -26,7 +26,8 @@ module Hyrax
|
|
26
26
|
# only includes ids of ordered members.
|
27
27
|
def ordered_member_ids
|
28
28
|
return [] if id.blank?
|
29
|
-
|
29
|
+
# Valkyrie members are always ordered
|
30
|
+
@ordered_member_ids ||= valkyrie? ? member_ids : query_for_ordered_ids
|
30
31
|
end
|
31
32
|
|
32
33
|
private
|
@@ -74,10 +74,17 @@ module Hyrax
|
|
74
74
|
Hyrax::ModelRegistry.work_classes.include?(hydra_model)
|
75
75
|
end
|
76
76
|
|
77
|
+
##
|
78
|
+
# @return [Boolean]
|
79
|
+
def valkyrie?
|
80
|
+
self['valkyrie_bsi']
|
81
|
+
end
|
82
|
+
|
77
83
|
# Method to return the model
|
78
84
|
def hydra_model(classifier: nil)
|
79
|
-
first('has_model_ssim')&.safe_constantize
|
80
|
-
|
85
|
+
model = first('has_model_ssim')&.safe_constantize
|
86
|
+
model = (first('has_model_ssim')&.+ 'Resource')&.safe_constantize if Hyrax.config.valkyrie_transition?
|
87
|
+
model || model_classifier(classifier).classifier(self).best_model
|
81
88
|
end
|
82
89
|
|
83
90
|
def depositor(default = '')
|
@@ -135,6 +142,10 @@ module Hyrax
|
|
135
142
|
self['visibility_ssi'] == indexed_lease_visibility
|
136
143
|
end
|
137
144
|
|
145
|
+
def extensions_and_mime_types
|
146
|
+
JSON.parse(self['extensions_and_mime_types_ssm'].first).map(&:with_indifferent_access) if self['extensions_and_mime_types_ssm']
|
147
|
+
end
|
148
|
+
|
138
149
|
private
|
139
150
|
|
140
151
|
def model_classifier(classifier)
|