Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I897 Bulkrax readiness for Hyku 6 and Hyrax 4 & 5 #898

Merged
merged 15 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/factories/bulkrax/valkyrie_object_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def create
result = transaction
.with_step_args(
# "work_resource.add_to_parent" => {parent_id: @related_parents_parsed_mapping, user: @user},
"work_resource.add_bulkrax_files" => { files: get_s3_files(remote_files: attributes["remote_files"]), user: @user },
"work_resource.#{Bulkrax::Container::ADD_BULKRAX_FILES}" => { files: get_s3_files(remote_files: attributes["remote_files"]), user: @user },
"change_set.set_user_as_depositor" => { user: @user },
"work_resource.change_depositor" => { user: @user },
'work_resource.save_acl' => { permissions_params: [attrs.try('visibility') || 'open'].compact }
Expand Down Expand Up @@ -83,7 +83,7 @@ def update

result = update_transaction
.with_step_args(
"work_resource.add_bulkrax_files" => { files: get_s3_files(remote_files: attributes["remote_files"]), user: @user }
"work_resource.#{Bulkrax::Container::ADD_BULKRAX_FILES}" => { files: get_s3_files(remote_files: attributes["remote_files"]), user: @user }

# TODO: uncomment when we upgrade Hyrax 4.x
# 'work_resource.save_acl' => { permissions_params: [attrs.try('visibility') || 'open'].compact }
Expand Down Expand Up @@ -165,12 +165,12 @@ def destroy_existing_files
private

def transaction
jeremyf marked this conversation as resolved.
Show resolved Hide resolved
Hyrax::Transactions::Container["work_resource.create_with_bulk_behavior"]
Hyrax::Transactions::Container["work_resource.#{Bulkrax::Container::CREATE_WITH_BULK_BEHAVIOR}"]
end

# Customize Hyrax::Transactions::WorkUpdate transaction with bulkrax
def update_transaction
Hyrax::Transactions::Container["work_resource.update_with_bulk_behavior"]
Hyrax::Transactions::Container["work_resource.#{Bulkrax::Container::UPDATE_WITH_BULK_BEHAVIOR}"]
end

# Query child FileSet in the resource/object
Expand Down
67 changes: 67 additions & 0 deletions app/models/concerns/bulkrax/has_mapping_ext.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true

module Bulkrax
module HasMappingExt
##
# Field of the model that can be supported
def field_supported?(field)
field = field.gsub("_attributes", "")

return false if excluded?(field)
return true if supported_bulkrax_fields.include?(field)

property_defined = factory_class.singleton_methods.include?(:properties) && factory_class.properties[field].present?

factory_class.method_defined?(field) && (Bulkrax::ValkyrieObjectFactory.schema_properties(factory_class).include?(field) || property_defined)
end

##
# Determine a multiple properties field
def multiple?(field)
@multiple_bulkrax_fields ||=
%W[
file
remote_files
rights_statement
#{related_parents_parsed_mapping}
#{related_children_parsed_mapping}
]

return true if @multiple_bulkrax_fields.include?(field)
return false if field == "model"

field_supported?(field) && (multiple_field?(field) || factory_class.singleton_methods.include?(:properties) && factory_class&.properties&.[](field)&.[]("multiple"))
end

def multiple_field?(field)
form_definition = schema_form_definitions[field.to_sym]
form_definition.nil? ? false : form_definition.multiple?
end

# override: we want to directly infer from a property being multiple that we should split when it's a String
# def multiple_metadata(content)
# return unless content

# case content
# when Nokogiri::XML::NodeSet
# content&.content
# when Array
# content
# when Hash
# Array.wrap(content)
# when String
# String(content).strip.split(Bulkrax.multi_value_element_split_on)
# else
# Array.wrap(content)
# end
# end

def schema_form_definitions
@schema_form_definitions ||= ::SchemaLoader.new.form_definitions_for(factory_class.name.underscore.to_sym)
end
end
end

[Bulkrax::HasMatchers, Bulkrax::HasMatchers.singleton_class].each do |mod|
mod.prepend Bulkrax::HasMappingExt
end
49 changes: 0 additions & 49 deletions app/services/bulkrax/transactions/steps/add_files.rb

This file was deleted.

42 changes: 42 additions & 0 deletions app/transactions/bulkrax/container.rb
laritakr marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true
require 'dry/container'

module Bulkrax
class Container
extend Dry::Container::Mixin

ADD_BULKRAX_FILES = 'add_bulkrax_files'
CREATE_WITH_BULK_BEHAVIOR = 'create_with_bulk_behavior'
CREATE_WITH_BULK_BEHAVIOR_STEPS = begin
steps = Hyrax::Transactions::WorkCreate::DEFAULT_STEPS.dup
steps[steps.index("work_resource.add_file_sets")] = "work_resource.#{Bulkrax::Container::ADD_BULKRAX_FILES}"
steps
end.freeze
UPDATE_WITH_BULK_BEHAVIOR = 'update_with_bulk_behavior'
UPDATE_WITH_BULK_BEHAVIOR_STEPS = begin
steps = Hyrax::Transactions::WorkUpdate::DEFAULT_STEPS.dup
steps[steps.index("work_resource.add_file_sets")] = "work_resource.#{Bulkrax::Container::ADD_BULKRAX_FILES}"
steps
end.freeze

namespace "work_resource" do |ops|
ops.register CREATE_WITH_BULK_BEHAVIOR do
Hyrax::Transactions::WorkCreate.new(steps: CREATE_WITH_BULK_BEHAVIOR_STEPS)
end

ops.register UPDATE_WITH_BULK_BEHAVIOR do
Hyrax::Transactions::WorkUpdate.new(steps: UPDATE_WITH_BULK_BEHAVIOR_STEPS)
end

# TODO: uninitialized constant Bulkrax::Container::InlineUploadHandler
# ops.register "add_file_sets" do
# Hyrax::Transactions::Steps::AddFileSets.new(handler: InlineUploadHandler)
# end

ops.register ADD_BULKRAX_FILES do
Bulkrax::Steps::AddFiles.new
end
end
end
end
Hyrax::Transactions::Container.merge(Bulkrax::Container)
47 changes: 47 additions & 0 deletions app/transactions/bulkrax/steps/add_files.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require "dry/monads"

module Bulkrax
module Steps
class AddFiles
include Dry::Monads[:result]

##
# @param [Class] handler
def initialize(handler: Hyrax::WorkUploadsHandler)
@handler = handler
end

##
# @param [Hyrax::Work] obj
# @param [Array<Fog::AWS::Storage::File>] file
# @param [User] user
#
# @return [Dry::Monads::Result]
def call(obj, files:, user:)
if files && user
begin
files.each do |file|
FileIngest.upload(
content_type: file.content_type,
file_body: StringIO.new(file.body),
filename: Pathname.new(file.key).basename,
last_modified: file.last_modified,
permissions: Hyrax::AccessControlList.new(resource: obj),
size: file.content_length,
user: user,
work: obj
)
end
rescue => e
Hyrax.logger.error(e)
return Failure[:failed_to_attach_file_sets, files]
end
end

Success(obj)
end
end
end
end
18 changes: 18 additions & 0 deletions app/transactions/bulkrax/transactions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'bulkrax/container'

module Bulkrax
##
# This is a parent module for DRY Transaction classes handling Bulkrax
# processes. Especially: transactions and steps for creating, updating, and
# destroying PCDM Objects are located here.
#
# @since 2.4.0
#
# @example
# Bulkrax::Transaction::Container['transaction_name'].call(:input)
#
# @see https://dry-rb.org/gems/dry-transaction/
module Transactions
end
end
4 changes: 4 additions & 0 deletions lib/bulkrax/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
module Bulkrax
class Engine < ::Rails::Engine
isolate_namespace Bulkrax

config.eager_load_paths += %W[#{config.root}/app/transactions]

initializer :append_migrations do |app|
if !app.root.to_s.match(root.to_s) && app.root.join('db/migrate').children.none? { |path| path.fnmatch?("*.bulkrax.rb") }
config.paths["db/migrate"].expanded.each do |expanded_path|
Expand All @@ -17,6 +20,7 @@ class Engine < ::Rails::Engine
require 'bulkrax/persistence_layer'
require 'bulkrax/persistence_layer/active_fedora_adapter' if defined?(ActiveFedora)
require 'bulkrax/persistence_layer/valkyrie_adapter' if defined?(Valkyrie)
require 'bulkrax/transactions' if defined?(Hyrax::Transactions)
end

config.generators do |g|
Expand Down
95 changes: 0 additions & 95 deletions lib/generators/bulkrax/templates/config/initializers/bulkrax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,98 +86,3 @@
if Object.const_defined?(:Hyrax) && ::Hyrax::DashboardController&.respond_to?(:sidebar_partials)
Hyrax::DashboardController.sidebar_partials[:repository_content] << "hyrax/dashboard/sidebar/bulkrax_sidebar_additions"
end

# TODO: move outside of initializer?
class BulkraxTransactionContainer
extend Dry::Container::Mixin

namespace "work_resource" do |ops|
ops.register "create_with_bulk_behavior" do
steps = Hyrax::Transactions::WorkCreate::DEFAULT_STEPS.dup
steps[steps.index("work_resource.add_file_sets")] = "work_resource.add_bulkrax_files"

Hyrax::Transactions::WorkCreate.new(steps: steps)
end

ops.register "update_with_bulk_behavior" do
steps = Hyrax::Transactions::WorkUpdate::DEFAULT_STEPS.dup
steps[steps.index("work_resource.add_file_sets")] = "work_resource.add_bulkrax_files"

Hyrax::Transactions::WorkUpdate.new(steps: steps)
end

# TODO: uninitialized constant BulkraxTransactionContainer::InlineUploadHandler
# ops.register "add_file_sets" do
# Hyrax::Transactions::Steps::AddFileSets.new(handler: InlineUploadHandler)
# end

ops.register "add_bulkrax_files" do
Bulkrax::Transactions::Steps::AddFiles.new
end
end
end
Hyrax::Transactions::Container.merge(BulkraxTransactionContainer)

# TODO: move outside of initializer?
module HasMappingExt
##
# Field of the model that can be supported
def field_supported?(field)
field = field.gsub("_attributes", "")

return false if excluded?(field)
return true if supported_bulkrax_fields.include?(field)

property_defined = factory_class.singleton_methods.include?(:properties) && factory_class.properties[field].present?

factory_class.method_defined?(field) && (Bulkrax::ValkyrieObjectFactory.schema_properties(factory_class).include?(field) || property_defined)
end

##
# Determine a multiple properties field
def multiple?(field)
@multiple_bulkrax_fields ||=
%W[
file
remote_files
rights_statement
#{related_parents_parsed_mapping}
#{related_children_parsed_mapping}
]

return true if @multiple_bulkrax_fields.include?(field)
return false if field == "model"

field_supported?(field) && (multiple_field?(field) || factory_class.singleton_methods.include?(:properties) && factory_class&.properties&.[](field)&.[]("multiple"))
end

def multiple_field?(field)
form_definition = schema_form_definitions[field.to_sym]
form_definition.nil? ? false : form_definition.multiple?
end

# override: we want to directly infer from a property being multiple that we should split when it's a String
# def multiple_metadata(content)
# return unless content

# case content
# when Nokogiri::XML::NodeSet
# content&.content
# when Array
# content
# when Hash
# Array.wrap(content)
# when String
# String(content).strip.split(Bulkrax.multi_value_element_split_on)
# else
# Array.wrap(content)
# end
# end

def schema_form_definitions
@schema_form_definitions ||= ::SchemaLoader.new.form_definitions_for(factory_class.name.underscore.to_sym)
end
end
[Bulkrax::HasMatchers, Bulkrax::HasMatchers.singleton_class].each do |mod|
mod.prepend HasMappingExt
end
Loading
Loading