hyrax 3.3.0 → 3.4.2
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/.circleci/config.yml +26 -17
- data/.dassie/.env +2 -1
- data/.dassie/Gemfile +1 -1
- data/.dassie/app/forms/collection_resource_form.rb +8 -0
- data/.dassie/app/indexers/collection_resource_indexer.rb +8 -0
- data/.dassie/app/models/collection_resource.rb +35 -0
- data/.dassie/config/initializers/file_services.rb +4 -0
- data/.dassie/config/initializers/hyrax.rb +12 -1
- data/.dassie/config/metadata/collection_resource.yaml +23 -0
- data/.dassie/db/seeds.rb +74 -17
- data/.dassie/spec/forms/collection_resource_form_spec.rb +13 -0
- data/.dassie/spec/indexers/collection_resource_indexer_spec.rb +14 -0
- data/.dassie/spec/models/collection_resource_spec.rb +13 -0
- data/.github/release.yml +26 -0
- data/.gitignore +3 -0
- data/.regen +1 -1
- data/.rubocop.yml +1 -1
- data/.rubocop_fixme.yml +22 -3
- data/CONTAINERS.md +18 -13
- data/Dockerfile +4 -3
- data/app/actors/hyrax/actors/file_actor.rb +6 -4
- data/app/actors/hyrax/actors/transfer_request_actor.rb +3 -7
- data/app/assets/javascripts/hyrax/analytics_events.js +8 -2
- data/app/assets/javascripts/hyrax/autocomplete/linked_data.es6 +1 -3
- data/app/assets/javascripts/hyrax/collections_v2.es6 +13 -0
- data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +1 -3
- data/app/controllers/concerns/hyrax/controller.rb +21 -0
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +83 -59
- data/app/controllers/hyrax/admin/admin_sets_controller.rb +105 -19
- data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +12 -19
- data/app/controllers/hyrax/batch_edits_controller.rb +12 -3
- data/app/controllers/hyrax/batch_uploads_controller.rb +4 -0
- data/app/controllers/hyrax/citations_controller.rb +1 -1
- data/app/controllers/hyrax/dashboard/collections_controller.rb +176 -83
- data/app/controllers/hyrax/single_use_links_viewer_controller.rb +1 -1
- data/app/forms/hyrax/forms/administrative_set_form.rb +19 -1
- data/app/forms/hyrax/forms/batch_edit_form.rb +1 -1
- data/app/forms/hyrax/forms/collection_form.rb +1 -1
- data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +21 -6
- data/app/forms/hyrax/forms/pcdm_collection_form.rb +30 -2
- data/app/forms/hyrax/forms/permission_template_form.rb +17 -9
- data/app/forms/hyrax/forms/resource_form.rb +23 -5
- data/app/forms/hyrax/forms/widgets/admin_set_visibility.rb +1 -1
- data/app/helpers/hyrax/collections_helper.rb +14 -0
- data/app/helpers/hyrax/membership_helper.rb +1 -1
- data/app/helpers/hyrax/trophy_helper.rb +1 -1
- data/app/helpers/hyrax/url_helper.rb +1 -1
- data/app/indexers/hyrax/administrative_set_indexer.rb +8 -2
- data/app/indexers/hyrax/deep_indexing_service.rb +1 -1
- data/app/indexers/hyrax/file_set_indexer.rb +1 -0
- data/app/indexers/hyrax/pcdm_collection_indexer.rb +3 -2
- data/app/indexers/hyrax/thumbnail_indexer.rb +31 -0
- data/app/indexers/hyrax/valkyrie_file_set_indexer.rb +6 -6
- data/app/indexers/hyrax/valkyrie_indexer.rb +4 -2
- data/app/indexers/hyrax/valkyrie_work_indexer.rb +13 -0
- data/app/inputs/controlled_vocabulary_input.rb +2 -0
- data/app/jobs/change_depositor_event_job.rb +47 -0
- data/app/jobs/characterize_job.rb +43 -3
- data/app/jobs/concerns/hyrax/members_permission_job_behavior.rb +1 -1
- data/app/jobs/content_depositor_change_event_job.rb +2 -1
- data/app/jobs/hyrax/propagate_change_depositor_job.rb +32 -0
- data/app/jobs/import_url_job.rb +4 -6
- data/app/jobs/inherit_permissions_job.rb +1 -1
- data/app/jobs/valkyrie_create_derivatives_job.rb +25 -0
- data/app/jobs/valkyrie_ingest_job.rb +41 -35
- data/app/models/admin_set.rb +10 -2
- data/app/models/collection_branding_info.rb +8 -6
- data/app/models/concerns/hyrax/collection_behavior.rb +3 -3
- data/app/models/concerns/hyrax/file_set/characterization.rb +7 -1
- data/app/models/concerns/hyrax/solr_document/metadata.rb +1 -0
- data/app/models/concerns/hyrax/solr_document_behavior.rb +9 -3
- data/app/models/concerns/hyrax/user.rb +11 -0
- data/app/models/concerns/hyrax/work_behavior.rb +1 -1
- data/app/models/featured_work_list.rb +0 -1
- data/app/models/hyrax/administrative_set.rb +36 -1
- data/app/models/hyrax/collection_type.rb +2 -2
- data/app/models/hyrax/file_metadata.rb +37 -3
- data/app/models/hyrax/file_set.rb +43 -4
- data/app/models/hyrax/group.rb +19 -0
- data/app/models/hyrax/pcdm_collection.rb +56 -1
- data/app/models/hyrax/permission_template.rb +11 -5
- data/app/models/hyrax/work.rb +91 -0
- data/app/models/job_io_wrapper.rb +1 -1
- data/app/models/proxy_deposit_request.rb +1 -1
- data/app/presenters/hyrax/admin_set_presenter.rb +2 -2
- data/app/presenters/hyrax/member_presenter_factory.rb +2 -4
- data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -2
- data/app/presenters/hyrax/work_show_presenter.rb +10 -6
- data/app/search_builders/hyrax/dashboard/collections_search_builder.rb +2 -2
- data/app/search_builders/hyrax/dashboard/managed_search_filters.rb +44 -4
- data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +2 -2
- data/app/search_builders/hyrax/my/collections_search_builder.rb +11 -4
- data/app/services/hyrax/access_control_list.rb +20 -6
- data/app/services/hyrax/adapters/nesting_index_adapter.rb +3 -3
- data/app/services/hyrax/admin_set_create_service.rb +21 -37
- data/app/services/hyrax/change_content_depositor_service.rb +2 -2
- data/app/services/hyrax/change_depositor_service.rb +70 -0
- data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +4 -6
- data/app/services/hyrax/collections/collection_member_service.rb +3 -5
- data/app/services/hyrax/collections/nested_collection_query_service.rb +24 -12
- data/app/services/hyrax/custom_queries/navigators/child_file_sets_navigator.rb +45 -0
- data/app/services/hyrax/custom_queries/navigators/child_filesets_navigator.rb +7 -2
- data/app/services/hyrax/custom_queries/navigators/parent_work_navigator.rb +54 -0
- data/app/services/hyrax/default_middleware_stack.rb +3 -0
- data/app/services/hyrax/file_set_derivatives_service.rb +21 -2
- data/app/services/hyrax/file_set_type_service.rb +2 -5
- data/app/services/hyrax/listeners/file_metadata_listener.rb +31 -1
- data/app/services/hyrax/listeners/member_cleanup_listener.rb +27 -11
- data/app/services/hyrax/listeners/metadata_index_listener.rb +39 -0
- data/app/services/hyrax/listeners/proxy_deposit_listener.rb +14 -8
- data/app/services/hyrax/location_service.rb +33 -0
- data/app/services/hyrax/multiple_membership_checker.rb +46 -1
- data/app/services/hyrax/resource_visibility_propagator.rb +1 -1
- data/app/services/hyrax/simple_schema_loader.rb +5 -1
- data/app/services/hyrax/solr_query_service.rb +12 -7
- data/app/services/hyrax/thumbnail_path_service.rb +1 -1
- data/app/services/hyrax/valkyrie_persist_derivatives.rb +50 -0
- data/app/services/hyrax/valkyrie_upload.rb +94 -0
- data/app/services/hyrax/work_uploads_handler.rb +0 -10
- data/app/services/hyrax/workflow/workflow_importer.rb +7 -9
- data/app/services/hyrax/workflow/workflow_schema.rb +3 -5
- data/app/strategies/hyrax/strategies/yaml_strategy.rb +4 -6
- data/app/uploaders/hyrax/uploaded_file_uploader.rb +4 -4
- data/app/utils/hyrax/data_destroyers/collection_branding_destroyer.rb +29 -0
- data/app/utils/hyrax/data_destroyers/collection_types_destroyer.rb +26 -0
- data/app/utils/hyrax/data_destroyers/default_admin_set_id_cache_destroyer.rb +26 -0
- data/app/utils/hyrax/data_destroyers/featured_works_destroyer.rb +27 -0
- data/app/utils/hyrax/data_destroyers/permission_templates_destroyer.rb +30 -0
- data/app/utils/hyrax/data_destroyers/repository_metadata_destroyer.rb +42 -0
- data/app/utils/hyrax/data_destroyers/stats_destroyer.rb +33 -0
- data/app/utils/hyrax/data_maintenance.rb +51 -0
- data/app/utils/hyrax/required_data_seeder.rb +21 -0
- data/app/utils/hyrax/required_data_seeders/collection_seeder.rb +26 -0
- data/app/utils/hyrax/required_data_seeders/collection_type_seeder.rb +36 -0
- data/app/utils/hyrax/test_data_seeder.rb +24 -0
- data/app/utils/hyrax/test_data_seeders/collection_seeder.rb +91 -0
- data/app/utils/hyrax/test_data_seeders/collection_type_seeder.rb +72 -0
- data/app/utils/hyrax/test_data_seeders/user_seeder.rb +52 -0
- data/app/validators/hyrax/collection_membership_validator.rb +39 -0
- data/app/views/catalog/_index_header_list_default.html.erb +8 -1
- data/app/views/catalog/_thumbnail_list_default.html.erb +8 -3
- data/app/views/collections/edit_fields/_based_near.html.erb +7 -7
- data/app/views/hyrax/admin/admin_sets/_form_participant_table.html.erb +2 -2
- data/app/views/hyrax/admin/admin_sets/_form_participants.html.erb +2 -2
- data/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb +2 -2
- data/app/views/hyrax/admin/admin_sets/_form_workflow.erb +1 -1
- data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
- data/app/views/hyrax/base/_form.html.erb +1 -1
- data/app/views/hyrax/base/_form_child_work_relationships.html.erb +1 -1
- data/app/views/hyrax/dashboard/collections/_default_group.html.erb +2 -2
- data/app/views/hyrax/dashboard/collections/_form.html.erb +24 -17
- data/app/views/hyrax/dashboard/collections/_form_branding.html.erb +1 -0
- data/app/views/hyrax/dashboard/collections/_form_discovery.html.erb +6 -3
- data/app/views/hyrax/dashboard/collections/_form_share.html.erb +2 -2
- data/app/views/hyrax/dashboard/collections/_form_share_table.html.erb +3 -3
- data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +2 -2
- data/app/views/hyrax/dashboard/sidebar/_activity.html.erb +1 -1
- data/app/views/hyrax/dashboard/works/_default_group.html.erb +1 -1
- data/app/views/hyrax/dashboard/works/_list_works.html.erb +1 -1
- data/app/views/hyrax/file_sets/_actions.html.erb +2 -2
- data/app/views/hyrax/my/_facet_pagination.html.erb +12 -9
- data/app/views/hyrax/my/_work_action_menu.html.erb +8 -9
- data/app/views/hyrax/my/collections/_default_group.html.erb +2 -2
- data/app/views/hyrax/my/collections/_list_collections.html.erb +2 -2
- data/app/views/hyrax/my/collections/index.html.erb +3 -2
- data/app/views/hyrax/my/works/_default_group.html.erb +1 -1
- data/app/views/hyrax/my/works/_list_works.html.erb +1 -2
- data/app/views/hyrax/my/works/_tabs.html.erb +6 -1
- data/app/views/hyrax/my/works/index.html.erb +4 -2
- data/chart/hyrax/Chart.yaml +11 -7
- data/chart/hyrax/README.md +22 -1
- data/chart/hyrax/templates/_helpers.tpl +4 -0
- data/chart/hyrax/templates/cron-embargo.yaml +5 -0
- data/chart/hyrax/templates/cron-lease.yaml +5 -0
- data/chart/hyrax/templates/deployment-worker.yaml +11 -0
- data/chart/hyrax/templates/ingress.yaml +7 -6
- data/chart/hyrax/values.yaml +152 -0
- data/config/features.rb +48 -50
- data/config/initializers/listeners.rb +0 -1
- data/config/initializers/{valkryrie_storage.rb → storage_adapter_initializer.rb} +5 -0
- data/config/locales/hyrax.de.yml +18 -17
- data/config/locales/hyrax.en.yml +30 -28
- data/config/locales/hyrax.es.yml +10 -9
- data/config/locales/hyrax.fr.yml +2 -1
- data/config/locales/hyrax.it.yml +3 -2
- data/config/locales/hyrax.pt-BR.yml +2 -1
- data/config/locales/hyrax.zh.yml +2 -1
- data/config/metadata/basic_metadata.yaml +2 -0
- data/config/metadata/core_metadata.yaml +1 -1
- data/docker-compose.yml +47 -42
- data/documentation/developing-your-hyrax-based-app.md +1 -1
- data/documentation/legacyREADME.md +1 -1
- data/hyrax.gemspec +5 -3
- data/lib/generators/hyrax/collection_resource/USAGE +20 -0
- data/lib/generators/hyrax/collection_resource/collection_resource_generator.rb +133 -0
- data/lib/generators/hyrax/collection_resource/templates/collection.rb.erb +34 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_form.rb.erb +7 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_form_spec.rb.erb +13 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_indexer.rb.erb +7 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_indexer_spec.rb.erb +13 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_metadata.yaml +22 -0
- data/lib/generators/hyrax/collection_resource/templates/collection_spec.rb.erb +12 -0
- data/lib/generators/hyrax/install_generator.rb +9 -0
- data/lib/hyrax/administrative_set_name.rb +18 -0
- data/lib/hyrax/collection_name.rb +2 -0
- data/lib/hyrax/configuration.rb +22 -0
- data/lib/hyrax/controlled_vocabularies/location.rb +9 -2
- data/lib/hyrax/controlled_vocabularies/resource_label_caching.rb +42 -0
- data/lib/hyrax/controlled_vocabularies.rb +1 -0
- data/lib/hyrax/publisher.rb +49 -0
- data/lib/hyrax/schema.rb +16 -13
- data/lib/hyrax/specs/capybara.rb +1 -1
- data/lib/hyrax/specs/shared_specs/hydra_works.rb +11 -5
- data/lib/hyrax/specs/shared_specs/indexers.rb +117 -3
- data/lib/hyrax/transactions/admin_set_create.rb +2 -1
- data/lib/hyrax/transactions/admin_set_destroy.rb +22 -0
- data/lib/hyrax/transactions/admin_set_update.rb +21 -0
- data/lib/hyrax/transactions/collection_destroy.rb +22 -0
- data/lib/hyrax/transactions/collection_update.rb +5 -2
- data/lib/hyrax/transactions/container.rb +97 -23
- data/lib/hyrax/transactions/create_work.rb +3 -0
- data/lib/hyrax/transactions/destroy_work.rb +3 -0
- data/lib/hyrax/transactions/steps/apply_collection_permission_template.rb +2 -0
- data/lib/hyrax/transactions/steps/apply_permission_template.rb +2 -0
- data/lib/hyrax/transactions/steps/apply_visibility.rb +2 -0
- data/lib/hyrax/transactions/steps/change_depositor.rb +46 -0
- data/lib/hyrax/transactions/steps/check_for_empty_admin_set.rb +36 -0
- data/lib/hyrax/transactions/steps/delete_access_control.rb +32 -0
- data/lib/hyrax/transactions/steps/delete_resource.rb +19 -3
- data/lib/hyrax/transactions/steps/destroy_work.rb +3 -1
- data/lib/hyrax/transactions/steps/ensure_permission_template.rb +2 -0
- data/lib/hyrax/transactions/steps/save.rb +24 -6
- data/lib/hyrax/transactions/steps/save_access_control.rb +2 -2
- data/lib/hyrax/transactions/steps/save_collection_banner.rb +59 -0
- data/lib/hyrax/transactions/steps/save_collection_logo.rb +109 -0
- data/lib/hyrax/transactions/steps/save_work.rb +3 -0
- data/lib/hyrax/transactions/steps/set_user_as_creator.rb +41 -0
- data/lib/hyrax/transactions/steps/update_work_members.rb +51 -0
- data/lib/hyrax/transactions/update_work.rb +4 -3
- data/lib/hyrax/transactions/work_create.rb +1 -1
- data/lib/hyrax/transactions/work_destroy.rb +2 -1
- data/lib/hyrax/transactions/work_update.rb +19 -0
- data/lib/hyrax/version.rb +1 -1
- data/lib/wings/active_fedora_converter/file_metadata_node.rb +48 -0
- data/lib/wings/active_fedora_converter/instance_builder.rb +68 -0
- data/lib/wings/active_fedora_converter.rb +3 -3
- data/lib/wings/attribute_transformer.rb +5 -1
- data/lib/wings/services/custom_queries/find_file_metadata.rb +19 -8
- data/lib/wings/setup.rb +3 -1
- data/lib/wings/valkyrie/persister.rb +2 -0
- data/lib/wings/valkyrie/query_service.rb +6 -7
- data/lib/wings/valkyrie/storage.rb +7 -1
- data/template.rb +1 -1
- metadata +99 -12
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hyrax
|
|
4
|
+
module CustomQueries
|
|
5
|
+
module Navigators
|
|
6
|
+
##
|
|
7
|
+
# Navigate from a resource to it's parent work.
|
|
8
|
+
#
|
|
9
|
+
# @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
|
|
10
|
+
# @since 3.4.0
|
|
11
|
+
class ParentWorkNavigator
|
|
12
|
+
# Define the queries that can be fulfilled by this navigator.
|
|
13
|
+
def self.queries
|
|
14
|
+
[:find_parent_work, :find_parent_work_id]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :query_service
|
|
18
|
+
|
|
19
|
+
def initialize(query_service:)
|
|
20
|
+
@query_service = query_service
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Find parent work of a given resource, and map to Valkyrie Resources
|
|
25
|
+
# @note There should be only one parent resource. A warning is logged if
|
|
26
|
+
# more than one resource is found and the first of the resources is returned.
|
|
27
|
+
# @param [Valkyrie::Resource] resource
|
|
28
|
+
#
|
|
29
|
+
# @return [Array<Valkyrie::Resource>]
|
|
30
|
+
def find_parent_work(resource:)
|
|
31
|
+
results = Hyrax.query_service.find_inverse_references_by(resource: resource,
|
|
32
|
+
property: :member_ids).select(&:work?)
|
|
33
|
+
if results.count > 1
|
|
34
|
+
Hyrax.logger.warn("#{resource.work? ? 'Work' : 'File set'} " \
|
|
35
|
+
"#{resource.id} is in #{results.count} works when it " \
|
|
36
|
+
"should be in no more than one.")
|
|
37
|
+
end
|
|
38
|
+
results.first
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Find the id of the parent work of a given resource, and map to Valkyrie Resources IDs
|
|
43
|
+
# @note There should be only one parent resource. A warning is logged if
|
|
44
|
+
# more than one resource is found and the first of the resources is returned.
|
|
45
|
+
# @param [Valkyrie::Resource] resource
|
|
46
|
+
#
|
|
47
|
+
# @return [Array<Valkyrie::ID>]
|
|
48
|
+
def find_parent_work_id(resource:)
|
|
49
|
+
find_parent_work(resource: resource)&.id
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -42,6 +42,9 @@ module Hyrax
|
|
|
42
42
|
# Decode the private/public/institution on the form into permisisons on
|
|
43
43
|
# the model
|
|
44
44
|
middleware.use Hyrax::Actors::InterpretVisibilityActor
|
|
45
|
+
#
|
|
46
|
+
# Handles transfering ownership of works from one user to another
|
|
47
|
+
middleware.use Hyrax::Actors::TransferRequestActor
|
|
45
48
|
|
|
46
49
|
# Copies default permissions from the PermissionTemplate to the work
|
|
47
50
|
middleware.use Hyrax::Actors::ApplyPermissionTemplateActor
|
|
@@ -3,13 +3,22 @@ module Hyrax
|
|
|
3
3
|
# Responsible for creating and cleaning up the derivatives of a file_set
|
|
4
4
|
class FileSetDerivativesService
|
|
5
5
|
attr_reader :file_set
|
|
6
|
-
delegate :
|
|
6
|
+
delegate :mime_type, to: :file_set
|
|
7
7
|
|
|
8
8
|
# @param file_set [Hyrax::FileSet] At least for this class, it must have #uri and #mime_type
|
|
9
9
|
def initialize(file_set)
|
|
10
10
|
@file_set = file_set
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
def uri
|
|
14
|
+
# If given a FileMetadata object, use its parent ID.
|
|
15
|
+
if file_set.respond_to?(:file_set_id)
|
|
16
|
+
file_set.file_set_id.to_s
|
|
17
|
+
else
|
|
18
|
+
file_set.uri
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
13
22
|
def cleanup_derivatives
|
|
14
23
|
derivative_path_factory.derivatives_for_reference(file_set).each do |path|
|
|
15
24
|
FileUtils.rm_f(path)
|
|
@@ -33,12 +42,22 @@ module Hyrax
|
|
|
33
42
|
# The destination_name parameter has to match up with the file parameter
|
|
34
43
|
# passed to the DownloadsController
|
|
35
44
|
def derivative_url(destination_name)
|
|
36
|
-
path = derivative_path_factory.derivative_path_for_reference(
|
|
45
|
+
path = derivative_path_factory.derivative_path_for_reference(derivative_url_target, destination_name)
|
|
37
46
|
URI("file://#{path}").to_s
|
|
38
47
|
end
|
|
39
48
|
|
|
40
49
|
private
|
|
41
50
|
|
|
51
|
+
# If given a FileMetadata object pass the file_set_id for derivative URL
|
|
52
|
+
# creation.
|
|
53
|
+
def derivative_url_target
|
|
54
|
+
if file_set.try(:file_set_id)
|
|
55
|
+
file_set.file_set_id.to_s
|
|
56
|
+
else
|
|
57
|
+
file_set
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
42
61
|
def supported_mime_types
|
|
43
62
|
file_set.class.pdf_mime_types +
|
|
44
63
|
file_set.class.office_document_mime_types +
|
|
@@ -17,13 +17,10 @@ module Hyrax
|
|
|
17
17
|
attr_reader :file_set
|
|
18
18
|
|
|
19
19
|
##
|
|
20
|
-
# @todo make `file_set_characterization_proxy` (or something better?)
|
|
21
|
-
# application-level configuration.
|
|
22
|
-
#
|
|
23
20
|
# @param [Hyrax::FileSet] file_set
|
|
24
21
|
# @param [Symbol] characterization_proxy defaults to the setting provided by
|
|
25
22
|
# the application's ActiveFedora `FileSet` class.
|
|
26
|
-
def initialize(file_set:, characterization_proxy:
|
|
23
|
+
def initialize(file_set:, characterization_proxy: Hyrax.config.characterization_proxy, query_service: Hyrax.custom_queries)
|
|
27
24
|
@file_set = file_set
|
|
28
25
|
@proxy_use = Hyrax::FileMetadata::Use.uri_for(use: characterization_proxy)
|
|
29
26
|
@queries = query_service
|
|
@@ -48,7 +45,7 @@ module Hyrax
|
|
|
48
45
|
private
|
|
49
46
|
|
|
50
47
|
def audio_types
|
|
51
|
-
return ::FileSet.audio_mime_types if defined?(::FileSet)
|
|
48
|
+
return ::FileSet.audio_mime_types if defined?(::FileSet) && ::FileSet.respond_to?(:audio_mime_types)
|
|
52
49
|
DEFAULT_AUDIO_TYPES
|
|
53
50
|
end
|
|
54
51
|
end
|
|
@@ -3,13 +3,43 @@
|
|
|
3
3
|
module Hyrax
|
|
4
4
|
module Listeners
|
|
5
5
|
##
|
|
6
|
-
# Listens for events related to Hyrax::FileMetadata
|
|
6
|
+
# Listens for events related to {Hyrax::FileMetadata}
|
|
7
7
|
class FileMetadataListener
|
|
8
|
+
##
|
|
9
|
+
# Called when 'file.characterized' event is published;
|
|
10
|
+
# allows post-characterization handling, like derivatives generation.
|
|
11
|
+
#
|
|
12
|
+
# @param [Dry::Events::Event] event
|
|
13
|
+
# @return [void]
|
|
14
|
+
def on_file_characterized(event)
|
|
15
|
+
CreateDerivativesJob
|
|
16
|
+
.perform_later(event[:file_set], event[:file_id], event[:path_hint])
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Called when 'file.metadata.updated' event is published; reindexes a
|
|
21
|
+
# {Hyrax::FileSet} when a file claiming to be its `pcdm_use:OriginalFile`
|
|
22
|
+
#
|
|
23
|
+
# @param [Dry::Events::Event] event
|
|
24
|
+
# @return [void]
|
|
25
|
+
def on_file_metadata_updated(event)
|
|
26
|
+
return unless event[:metadata].original_file?
|
|
27
|
+
|
|
28
|
+
file_set = Hyrax.query_service.find_by(id: event[:metadata].file_set_id)
|
|
29
|
+
Hyrax.index_adapter.save(resource: file_set)
|
|
30
|
+
rescue Valkyrie::Persistence::ObjectNotFoundError => err
|
|
31
|
+
Hyrax.logger.warn "tried to index file with id #{event[:metadata].id} " \
|
|
32
|
+
"in response to an event of type #{event.id} but " \
|
|
33
|
+
"encountered an error #{err.message}. should this " \
|
|
34
|
+
"object be in a FileSet #{event[:metadata]}"
|
|
35
|
+
end
|
|
36
|
+
|
|
8
37
|
##
|
|
9
38
|
# Called when 'object.file.uploaded' event is published
|
|
10
39
|
# @param [Dry::Events::Event] event
|
|
11
40
|
# @return [void]
|
|
12
41
|
def on_object_file_uploaded(event)
|
|
42
|
+
# Run characterization
|
|
13
43
|
Hyrax.config
|
|
14
44
|
.characterization_service
|
|
15
45
|
.run(metadata: event[:metadata], file: event[:metadata].file)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Hyrax
|
|
4
4
|
module Listeners
|
|
5
5
|
##
|
|
6
|
-
# Listens for
|
|
6
|
+
# Listens for resource deleted events and cleans up associated members
|
|
7
7
|
class MemberCleanupListener
|
|
8
8
|
# Called when 'object.deleted' event is published
|
|
9
9
|
# @param [Dry::Events::Event] event
|
|
@@ -12,16 +12,32 @@ module Hyrax
|
|
|
12
12
|
return unless event.payload.key?(:object) # legacy callback
|
|
13
13
|
return if event[:object].is_a?(ActiveFedora::Base) # handled by legacy code
|
|
14
14
|
|
|
15
|
-
Hyrax.custom_queries.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
Hyrax.custom_queries.find_child_file_sets(resource: event[:object]).each do |file_set|
|
|
16
|
+
Hyrax.persister.delete(resource: file_set)
|
|
17
|
+
Hyrax.publisher
|
|
18
|
+
.publish('object.deleted', object: file_set, id: file_set.id, user: event[:user])
|
|
19
|
+
rescue StandardError # we don't uncaught errors looping filesets
|
|
20
|
+
Hyrax.logger.warn "Failed to delete #{file_set.class}:#{file_set.id} " \
|
|
21
|
+
"during cleanup for resource: #{event[:object]}. " \
|
|
22
|
+
'This member may now be orphaned.'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Called when 'collection.deleted' event is published
|
|
27
|
+
# @param [Dry::Events::Event] event
|
|
28
|
+
# @return [void]
|
|
29
|
+
def on_collection_deleted(event)
|
|
30
|
+
return unless event.payload.key?(:collection) # legacy callback
|
|
31
|
+
return if event[:collection].is_a?(ActiveFedora::Base) # handled by legacy code
|
|
32
|
+
|
|
33
|
+
Hyrax.custom_queries.find_members_of(collection: event[:collection]).each do |resource|
|
|
34
|
+
resource.member_of_collection_ids -= [event[:collection].id]
|
|
35
|
+
Hyrax.persister.save(resource: resource)
|
|
36
|
+
Hyrax.publisher
|
|
37
|
+
.publish('collection.membership.updated', collection: event[:collection], user: event[:user])
|
|
38
|
+
rescue StandardError
|
|
39
|
+
Hyrax.logger.warn "Failed to remove collection reference from #{work.class}:#{work.id} " \
|
|
40
|
+
"during cleanup for collection: #{event[:collection]}. "
|
|
25
41
|
end
|
|
26
42
|
end
|
|
27
43
|
end
|
|
@@ -22,6 +22,34 @@ module Hyrax
|
|
|
22
22
|
Hyrax.index_adapter.save(resource: event[:collection])
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
##
|
|
26
|
+
# Re-index the resource.
|
|
27
|
+
#
|
|
28
|
+
# Called when 'file.metadata.updated' event is published
|
|
29
|
+
# @param [Dry::Events::Event] event
|
|
30
|
+
# @return [void]
|
|
31
|
+
def on_file_metadata_updated(event)
|
|
32
|
+
return unless resource? event[:metadata]
|
|
33
|
+
Hyrax.index_adapter.save(resource: event[:metadata])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Re-index the resource.
|
|
38
|
+
#
|
|
39
|
+
# Called when 'object.membership.updated' event is published
|
|
40
|
+
# @param [Dry::Events::Event] event
|
|
41
|
+
# @return [void]
|
|
42
|
+
def on_object_membership_updated(event)
|
|
43
|
+
resource = event.to_h.fetch(:object) { Hyrax.query_service.find_by(id: event[:object_id]) }
|
|
44
|
+
return unless resource?(resource)
|
|
45
|
+
|
|
46
|
+
Hyrax.index_adapter.save(resource: resource)
|
|
47
|
+
rescue Valkyrie::Persistence::ObjectNotFoundError => err
|
|
48
|
+
Hyrax.logger.error("Tried to index for an #{event.id} event with " \
|
|
49
|
+
"payload #{event.payload}, but failed due to error:\n"\
|
|
50
|
+
"\t#{err.message}")
|
|
51
|
+
end
|
|
52
|
+
|
|
25
53
|
##
|
|
26
54
|
# Re-index the resource.
|
|
27
55
|
#
|
|
@@ -44,6 +72,17 @@ module Hyrax
|
|
|
44
72
|
Hyrax.index_adapter.delete(resource: event[:object])
|
|
45
73
|
end
|
|
46
74
|
|
|
75
|
+
##
|
|
76
|
+
# Remove the resource from the index.
|
|
77
|
+
#
|
|
78
|
+
# Called when 'collection.deleted' event is published
|
|
79
|
+
# @param [Dry::Events::Event] event
|
|
80
|
+
# @return [void]
|
|
81
|
+
def on_collection_deleted(event)
|
|
82
|
+
return unless resource?(event.payload[:collection])
|
|
83
|
+
Hyrax.index_adapter.delete(resource: event[:collection])
|
|
84
|
+
end
|
|
85
|
+
|
|
47
86
|
private
|
|
48
87
|
|
|
49
88
|
def resource?(resource)
|
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
module Hyrax
|
|
4
4
|
module Listeners
|
|
5
5
|
##
|
|
6
|
-
#
|
|
6
|
+
# @deprecated transfer requests are now carried out synchronously during
|
|
7
|
+
# object save
|
|
8
|
+
#
|
|
9
|
+
## Listens for deposit events, and checks for proxy situations. When a user
|
|
7
10
|
# deposits an item `on_behalf_of` another, ensures transfer is handled.
|
|
8
11
|
class ProxyDepositListener
|
|
9
12
|
##
|
|
10
13
|
# Called when 'object.deposited' event is published
|
|
11
|
-
# @param [Dry::Events::Event]
|
|
14
|
+
# @param [Dry::Events::Event] _event
|
|
12
15
|
# @return [void]
|
|
13
|
-
def on_object_deposited(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
def on_object_deposited(_event)
|
|
17
|
+
Deprecation.warn(
|
|
18
|
+
"The ProxyDepositListener was deprecated, effective immediately, in \
|
|
19
|
+
response to a difficult-to-diagnose race condition bug. This listener \
|
|
20
|
+
is now a no-op. To retain functionality ensure that \
|
|
21
|
+
DefaultMiddlewareStack is configured to use \
|
|
22
|
+
Hyrax::Actors::TransferRequestActor. To quiet this deprecation remove any \
|
|
23
|
+
local initializer configuration that subscribes this listener."
|
|
24
|
+
)
|
|
19
25
|
end
|
|
20
26
|
end
|
|
21
27
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Hyrax
|
|
3
|
+
class LocationService < ::Qa::Authorities::Geonames
|
|
4
|
+
CACHE_KEY_PREFIX = 'hyrax_geonames_label-v1-'
|
|
5
|
+
CACHE_EXPIRATION = 1.week
|
|
6
|
+
|
|
7
|
+
def full_label(uri)
|
|
8
|
+
return if uri.blank?
|
|
9
|
+
id = extract_id uri
|
|
10
|
+
Rails.cache.fetch(cache_key(id), expires_in: CACHE_EXPIRATION) do
|
|
11
|
+
label.call(find(id))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def extract_id(obj)
|
|
18
|
+
uri = case obj
|
|
19
|
+
when String
|
|
20
|
+
URI(obj)
|
|
21
|
+
when URI
|
|
22
|
+
obj
|
|
23
|
+
else
|
|
24
|
+
raise ArgumentError, "#{obj} is not a valid type"
|
|
25
|
+
end
|
|
26
|
+
uri.path.split('/').last
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def cache_key(id)
|
|
30
|
+
"#{CACHE_KEY_PREFIX}#{id}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -11,6 +11,28 @@ module Hyrax
|
|
|
11
11
|
@item = item
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# @api public
|
|
15
|
+
#
|
|
16
|
+
# Validate member_of_collection_ids does not have any membership conflicts
|
|
17
|
+
# based on the collection types of the members.
|
|
18
|
+
#
|
|
19
|
+
# Collections that have a collection type declaring
|
|
20
|
+
# `allow_multiple_membership` as `false` require that its members do not
|
|
21
|
+
# also belong to other collections of the same type.
|
|
22
|
+
#
|
|
23
|
+
# @return [True, String] true if no conflicts; otherwise, an error message string
|
|
24
|
+
# @deprecated Use #check instead; for removal in 4.0.0
|
|
25
|
+
def validate
|
|
26
|
+
Deprecation.warn "#{self.class}##{__method__} is deprecated; use #check instead."
|
|
27
|
+
return true if item.member_of_collection_ids.empty? || item.member_of_collection_ids.count <= 1
|
|
28
|
+
return true unless single_membership_collection_types_exist?
|
|
29
|
+
|
|
30
|
+
collections_to_check = filter_to_single_membership_collections(item.member_of_collection_ids)
|
|
31
|
+
problematic_collections = check_collections(collections_to_check)
|
|
32
|
+
errs = build_error_message(problematic_collections)
|
|
33
|
+
errs.presence || true
|
|
34
|
+
end
|
|
35
|
+
|
|
14
36
|
# @api public
|
|
15
37
|
#
|
|
16
38
|
# Scan a list of collection_ids for multiple single-membership collections.
|
|
@@ -42,15 +64,18 @@ module Hyrax
|
|
|
42
64
|
|
|
43
65
|
private
|
|
44
66
|
|
|
67
|
+
# @return [Boolean] true if there a any collection types that restrict membership
|
|
45
68
|
def single_membership_collection_types_exist?
|
|
46
69
|
single_membership_collection_types_gids.present?
|
|
47
70
|
end
|
|
48
71
|
|
|
72
|
+
# @return [Array<String] global ids of collection types that restrict membership
|
|
49
73
|
def single_membership_collection_types_gids
|
|
50
74
|
@single_membership_collection_types_gids ||=
|
|
51
75
|
Hyrax::CollectionType.gids_that_do_not_allow_multiple_membership&.map(&:to_s)
|
|
52
76
|
end
|
|
53
77
|
|
|
78
|
+
# @return [Array<Hyrax::PcdmCollection>] list of collection instances for single membership collections
|
|
54
79
|
def filter_to_single_membership_collections(collection_ids)
|
|
55
80
|
return [] if collection_ids.blank?
|
|
56
81
|
field_pairs = {
|
|
@@ -58,11 +83,14 @@ module Hyrax
|
|
|
58
83
|
}
|
|
59
84
|
Hyrax::SolrQueryService.new
|
|
60
85
|
.with_generic_type(generic_type: "Collection")
|
|
61
|
-
.with_ids(ids: Array
|
|
86
|
+
.with_ids(ids: Array(collection_ids).map(&:to_s))
|
|
62
87
|
.with_field_pairs(field_pairs: field_pairs, join_with: ' OR ')
|
|
63
88
|
.get_objects(use_valkyrie: true).to_a
|
|
64
89
|
end
|
|
65
90
|
|
|
91
|
+
# @param proposed [Array<Hyrax::PcdmCollection>] collections with restricted membership that are being added
|
|
92
|
+
# @param include_current_members [Boolean] true if current collections for item should also be checked
|
|
93
|
+
# @return [Array<Hyrax::PcdmCollection>] collections with restricted membership
|
|
66
94
|
def collections_to_check(proposed, include_current_members)
|
|
67
95
|
# ActorStack does a wholesale collection membership replacement, such that
|
|
68
96
|
# proposed collections include existing and new collections. Parameter
|
|
@@ -72,6 +100,19 @@ module Hyrax
|
|
|
72
100
|
proposed | filter_to_single_membership_collections(item.member_of_collection_ids)
|
|
73
101
|
end
|
|
74
102
|
|
|
103
|
+
# @param collections_to_check [Array<Hyrax::PcdmCollection>] collections with restricted membership
|
|
104
|
+
# @return [Array<Array>] collections groups by collection type
|
|
105
|
+
# @example example return result
|
|
106
|
+
# [
|
|
107
|
+
# [
|
|
108
|
+
# <Collection(id: 1, collection_type_gid: 1, ...)>,
|
|
109
|
+
# <Collection(id: 4, collection_type_gid: 1, ...)>
|
|
110
|
+
# ],
|
|
111
|
+
# [
|
|
112
|
+
# <Collection(id: 13, collection_type_gid: 8, ...)>,
|
|
113
|
+
# <Collection(id: 26, collection_type_gid: 8, ...)>
|
|
114
|
+
# ]
|
|
115
|
+
# ]
|
|
75
116
|
def check_collections(collections_to_check)
|
|
76
117
|
# uniq insures we include a collection only once when it is in the list multiple
|
|
77
118
|
# group_by groups collections of the same collection type together
|
|
@@ -82,6 +123,7 @@ module Hyrax
|
|
|
82
123
|
.select { |_gid, list| list.count > 1 }
|
|
83
124
|
end
|
|
84
125
|
|
|
126
|
+
# @return [nil, String] nil if no errors; otherwise, errors appended into a single human readable message
|
|
85
127
|
def build_error_message(problematic_collections)
|
|
86
128
|
return if problematic_collections.blank?
|
|
87
129
|
error_message_clauses = problematic_collections.map do |gid, list|
|
|
@@ -93,10 +135,13 @@ module Hyrax
|
|
|
93
135
|
"#{error_message_clauses.join('; ')}"
|
|
94
136
|
end
|
|
95
137
|
|
|
138
|
+
# @return [String] title of the collection type
|
|
96
139
|
def collection_type_title_from_gid(gid)
|
|
97
140
|
Hyrax::CollectionType.find_by_gid(gid).title
|
|
98
141
|
end
|
|
99
142
|
|
|
143
|
+
# @return [String] comma separated (with and before final) list of titles
|
|
144
|
+
# @example "Title 1, Title 2, and Title 3"
|
|
100
145
|
def collection_titles_from_list(collection_list)
|
|
101
146
|
collection_list.map do |collection|
|
|
102
147
|
collection.title.first
|
|
@@ -39,7 +39,7 @@ module Hyrax
|
|
|
39
39
|
#
|
|
40
40
|
# @raise [RuntimeError] if visibility propagation fails
|
|
41
41
|
def propagate
|
|
42
|
-
queries.
|
|
42
|
+
queries.find_child_file_sets(resource: source).each do |file_set|
|
|
43
43
|
file_set.visibility = source.visibility
|
|
44
44
|
embargo_manager.copy_embargo_to(target: file_set)
|
|
45
45
|
lease_manager.copy_lease_to(target: file_set)
|
|
@@ -76,7 +76,11 @@ module Hyrax
|
|
|
76
76
|
##
|
|
77
77
|
# @return [Dry::Types::Type]
|
|
78
78
|
def type
|
|
79
|
-
collection_type = config['multiple']
|
|
79
|
+
collection_type = if config['multiple']
|
|
80
|
+
Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) }
|
|
81
|
+
else
|
|
82
|
+
Identity
|
|
83
|
+
end
|
|
80
84
|
collection_type.of(type_for(config['type']))
|
|
81
85
|
end
|
|
82
86
|
|
|
@@ -59,10 +59,11 @@ module Hyrax
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
##
|
|
62
|
+
# @param join_with [String] the connector (eg. 'AND', 'OR') used to join each clause (default: 'AND')
|
|
62
63
|
# @return [String] the combined query that can be submitted to solr
|
|
63
|
-
def build
|
|
64
|
+
def build(join_with: 'AND')
|
|
64
65
|
return 'id:NEVER_USE_THIS_ID' if @query.blank? # forces this method to always return a valid solr query
|
|
65
|
-
@query.join(
|
|
66
|
+
@query.join(padded_join_with(join_with))
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
##
|
|
@@ -106,8 +107,8 @@ module Hyrax
|
|
|
106
107
|
|
|
107
108
|
##
|
|
108
109
|
# @param field_pairs [Hash] a list of pairs of property name and values (e.g. { field1: values, field2: values })
|
|
109
|
-
# @param join_with [String] the connector used to join the field pairs (default: '
|
|
110
|
-
# @param type [String] type of query to run.
|
|
110
|
+
# @param join_with [String] the connector (eg. 'AND', 'OR') used to join the field pairs (default: 'AND')
|
|
111
|
+
# @param type [String] type of query to run (e.g. 'raw', 'field', 'terms') (default: 'field')
|
|
111
112
|
# @return [SolrQueryService] the existing service with field_pair query appended
|
|
112
113
|
def with_field_pairs(field_pairs: {}, join_with: default_join_with, type: 'field')
|
|
113
114
|
pairs_query = construct_query_for_pairs(field_pairs, join_with, type)
|
|
@@ -140,7 +141,7 @@ module Hyrax
|
|
|
140
141
|
|
|
141
142
|
# Construct a solr query from a list of pairs (e.g. { field1: values, field2: values })
|
|
142
143
|
# @param [Hash] field_pairs a list of pairs of property name and values
|
|
143
|
-
# @param [String] join_with the value we're joining the clauses with (default: '
|
|
144
|
+
# @param [String] join_with the value (e.g. 'AND', 'OR') we're joining the clauses with (default: 'AND')
|
|
144
145
|
# @param [String] type of query to run. Either 'raw' or 'field' (default: 'field')
|
|
145
146
|
# @return [String] a solr query
|
|
146
147
|
# @example
|
|
@@ -150,7 +151,7 @@ module Hyrax
|
|
|
150
151
|
clauses = pairs_to_clauses(field_pairs, type)
|
|
151
152
|
return "" if clauses.count.zero?
|
|
152
153
|
return clauses.first if clauses.count == 1
|
|
153
|
-
"(#{clauses.join(join_with)})"
|
|
154
|
+
"(#{clauses.join(padded_join_with(join_with))})"
|
|
154
155
|
end
|
|
155
156
|
|
|
156
157
|
# Construct a solr query from the model (e.g. Collection, Monograph)
|
|
@@ -184,7 +185,11 @@ module Hyrax
|
|
|
184
185
|
end
|
|
185
186
|
|
|
186
187
|
def default_join_with
|
|
187
|
-
'
|
|
188
|
+
'AND'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def padded_join_with(join_with)
|
|
192
|
+
" #{join_with.strip} "
|
|
188
193
|
end
|
|
189
194
|
|
|
190
195
|
# @param [Array<Array>] pairs a list of (key, value) pairs. The value itself may
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Hyrax
|
|
3
|
+
class ValkyriePersistDerivatives < Hydra::Derivatives::PersistOutputFileService
|
|
4
|
+
# Persists a derivative using the defined Valkyrie storage adapter
|
|
5
|
+
#
|
|
6
|
+
# This Service conforms to the signature of `Hydra::Derivatives::PersistOutputFileService`.
|
|
7
|
+
# This service is a Valkyrized alternative to the default Hydra::Derivatives::PersistOutputFileService.
|
|
8
|
+
# This service will always update existing and does not do versioning of persisted files.
|
|
9
|
+
#
|
|
10
|
+
# to replace the default AF derivative pipeline, set
|
|
11
|
+
# ```
|
|
12
|
+
# Hydra::Derivatives.config.output_file_service = Hyrax::ValkyriePersistDerivatives
|
|
13
|
+
# Hydra::Derivatives.config.source_file_service = Hyrax::LocalFileService
|
|
14
|
+
# ```
|
|
15
|
+
#
|
|
16
|
+
# @param [#read] stream the derivative filestream
|
|
17
|
+
# @param [Hash] directives
|
|
18
|
+
# @option directives [String] :url a url to the file destination
|
|
19
|
+
def self.call(stream, directives)
|
|
20
|
+
filepath = URI(directives.fetch(:url)).path
|
|
21
|
+
fileset_id = fileset_id_from_path(filepath)
|
|
22
|
+
fileset = Hyrax.metadata_adapter.query_service.find_by(id: fileset_id)
|
|
23
|
+
|
|
24
|
+
# Valkyrie storage adapters will typically expect an IO-like object that
|
|
25
|
+
# responds to #path -- here we only have a StringIO, so some
|
|
26
|
+
# transformation is in order
|
|
27
|
+
tmpfile = Tempfile.new(fileset_id, encoding: 'ascii-8bit')
|
|
28
|
+
tmpfile.write stream.read
|
|
29
|
+
|
|
30
|
+
Rails.logger.debug "Uploading thumbnail for FileSet #{fileset_id} as #{filepath}"
|
|
31
|
+
Hyrax.config.derivatives_storage_adapter.upload(
|
|
32
|
+
file: tmpfile,
|
|
33
|
+
original_filename: filepath,
|
|
34
|
+
resource: fileset
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The filepath will look something like
|
|
39
|
+
# /app/samvera/hyrax-webapp/derivatives/95/93/tv/12/3-thumbnail.jpeg and
|
|
40
|
+
# we want to extract the FileSet id, which in this case would be 9593tv123
|
|
41
|
+
#
|
|
42
|
+
# @param [String] path
|
|
43
|
+
# @return [String]
|
|
44
|
+
def self.fileset_id_from_path(path)
|
|
45
|
+
path.sub(Hyrax.config.derivatives_path.to_s, "")
|
|
46
|
+
.sub(/-[^\/]+\..*$/, "")
|
|
47
|
+
.delete("/")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|