Skip to content

Commit

Permalink
🧹 Add indexing paths for Valkyrie resource
Browse files Browse the repository at this point in the history
This commit will add indexing paths for Valkyrie resources.  The
`IiifPrint::SimpleSchemaLoaderDecorator` is introduced here to add the
`IiifPrint::Engine.root` path to the schema load path so we can keep the
yaml in the gem and not have to copy it over to the host app.
  • Loading branch information
kirkkwang committed Jan 19, 2024
1 parent f0d50f2 commit 5ab4c2a
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 10 deletions.
34 changes: 29 additions & 5 deletions app/indexers/concerns/iiif_print/child_indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,40 @@ def self.decorate_work_types!
next unless work_type.respond_to?(:iiif_print_config?)
next unless work_type.iiif_print_config?

work_type.send(:include, IiifPrint::SetChildFlag) unless work_type.included_modules.include?(IiifPrint::SetChildFlag)
indexer = work_type.indexer
unless indexer.respond_to?(:iiif_print_lineage_service)
indexer.prepend(self)
indexer.class_attribute(:iiif_print_lineage_service, default: IiifPrint::LineageService)
if IiifPrint.use_valkyrie?(work_type)
decorate_valkyrie_resource(work_type)
else
decorate_af_object(work_type)
end

@indexer.prepend(self).class_attribute(:iiif_print_lineage_service, default: IiifPrint::LineageService) unless @indexer.respond_to?(:iiif_print_lineage_service)
work_type::GeneratedResourceSchema.send(:include, IiifPrint::SetChildFlag) if work_type.const_defined?(:GeneratedResourceSchema)
end
end

def self.decorate_valkyrie_resource(work_type)
work_type.send(:include, Hyrax::Schema(:child_works_from_pdf_splitting)) unless work_type.included_modules.include?(Hyrax::Schema(:child_works_from_pdf_splitting))
@indexer = "#{work_type.to_s}Indexer".constantize
@indexer.send(:include, Hyrax::Indexer(:child_works_from_pdf_splitting)) unless @indexer.included_modules.include?(Hyrax::Indexer(:child_works_from_pdf_splitting))
end

def self.decorate_af_object(work_type)
work_type.send(:include, IiifPrint::SetChildFlag) unless work_type.included_modules.include?(IiifPrint::SetChildFlag)
@indexer = work_type.indexer
end

def to_solr
super.tap do |index_document|
index_document['is_page_of_ssim'] = iiif_print_lineage_service.ancestor_ids_for(resource)

# Due to a long-standing hack in Hyrax, the file_set_ids_ssim contains both file_set_ids and
# child work ids.
#
# See https://github.com/samvera/hyrax/blob/2b807fe101176d594129ef8a8fe466d3d03a372b/app/indexers/hyrax/work_indexer.rb#L15-L18
index_document['file_set_ids_ssim'] = iiif_print_lineage_service.descendent_member_ids_for(resource)
end
end

def generate_solr_document
super.tap do |solr_doc|
solr_doc['is_child_bsi'] ||= object.is_child
Expand Down
13 changes: 13 additions & 0 deletions app/services/iiif_print/simple_schema_loader_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

# OVERRIDE Hyrax v5.0.0rc2 to add schemas that are located in config/metadata/*.yaml

module IiifPrint
module SimpleSchemaLoaderDecorator
private

def config_search_paths
super << IiifPrint::Engine.root
end
end
end
21 changes: 21 additions & 0 deletions config/metadata/child_works_from_pdf_splitting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
attributes:
is_child:
type: bool
multiple: false
index_keys:
- "is_child_bsi"
form:
required: false
primary: false
multiple: false
predicate: "http://id.loc.gov/vocabulary/identifiers/isChild"
split_from_pdf_id:
type: string
multiple: false
index_keys:
- "split_from_pdf_id_ssi"
form:
required: false
primary: false
multiple: false
predicate: "http://id.loc.gov/vocabulary/identifiers/splitFromPdfId"
19 changes: 16 additions & 3 deletions lib/iiif_print.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ def self.grandparent_for(file_set)
parent_of_file_set&.member_of&.find(&:work?)
end

def self.use_valkyrie?(obj)
return obj.ancestors.include?(Valkyrie::Resource) if obj.is_a? Class
return obj.is_a? Valkyrie::Resource if obj.is_a? Valkyrie::Resource

false
end

DEFAULT_MODEL_CONFIGURATION = {
# Split a PDF into individual page images and create a new child work for each image.
pdf_splitter_job: IiifPrint::Jobs::ChildWorksFromPdfJob,
Expand Down Expand Up @@ -127,12 +134,15 @@ def self.grandparent_for(file_set)
# @see IiifPrint::DEFAULT_MODEL_CONFIGURATION
# @todo Because not every job will split PDFs and write to a child model. May want to introduce
# an alternative splitting method to create new filesets on the existing work instead of new child works.
# rubocop:disable Metrics/MethodLength
def self.model_configuration(**kwargs)
Module.new do
extend ActiveSupport::Concern

class_method do
def iiif_print_config?; true; end
class_methods do
def iiif_print_config?
true
end
end

# We don't know what you may want in your configuration, but from this gems implementation,
Expand All @@ -145,9 +155,12 @@ def iiif_print_config?; true; end
@iiif_print_config ||= ModelConfig.new(**kwargs)
end

def iiif_print_config?; true; end
def iiif_print_config?
true
end
end
end
# rubocop:enable Metrics/MethodLength

# @api public
#
Expand Down
1 change: 1 addition & 0 deletions lib/iiif_print/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Engine < ::Rails::Engine
Hyrax::IiifManifestPresenter.prepend(IiifPrint::IiifManifestPresenterBehavior)
Hyrax::IiifManifestPresenter::Factory.prepend(IiifPrint::IiifManifestPresenterFactoryBehavior)
Hyrax::ManifestBuilderService.prepend(IiifPrint::ManifestBuilderServiceBehavior)
Hyrax::SimpleSchemaLoader.prepend(IiifPrint::SimpleSchemaLoaderDecorator)
Hyrax::Renderers::FacetedAttributeRenderer.prepend(Hyrax::Renderers::FacetedAttributeRendererDecorator)
Hyrax::WorksControllerBehavior.prepend(IiifPrint::WorksControllerBehaviorDecorator)
# Hyku::WorksControllerBehavior was introduced in Hyku v6.0.0+
Expand Down
22 changes: 20 additions & 2 deletions lib/iiif_print/lineage_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@ module LineageService
# @return [Array<String>]
def self.ancestor_ids_for(object)
ancestor_ids ||= []
object.in_works.each do |work|
object_in_works(object).each do |work|
ancestor_ids << ancestry_identifier_for(work)
ancestor_ids += ancestor_ids_for(work) if work.is_child
end
ancestor_ids.flatten.compact.uniq
end

def self.object_in_works(object)
if IiifPrint.use_valkyrie?(object)
Array.wrap(Hyrax.custom_queries.find_parent_work(resource: object))
else
object.in_works
end
end

##
# @api public
#
Expand All @@ -50,13 +58,23 @@ def self.descendent_member_ids_for(object)
# The Hydara::Works implementation of file_set_ids is "members.select(&:file_set?).map(&:id)";
# so no sense doing `object.file_set_ids + object.member_ids`
file_set_ids = object.member_ids
object.ordered_works&.each do |child|
object_ordered_works(object)&.each do |child|
file_set_ids += descendent_member_ids_for(child)
end
file_set_ids.flatten.uniq.compact
end
class << self
alias descendent_file_set_ids_for descendent_member_ids_for
end

def self.object_ordered_works(object)
if IiifPrint.use_valkyrie?(object)
child_file_set_ids = Hyrax.custom_queries.find_child_file_set_ids(resource: object).to_a
child_work_ids = Hyrax.custom_queries.find_child_work_ids(resource: object).to_a
child_file_set_ids + child_work_ids
else
object.ordered_works
end
end
end
end
36 changes: 36 additions & 0 deletions spec/iiif_print_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,42 @@
end
end

describe '.use_valkyrie?' do
context 'with valkyrie' do
class SomeValkyrieResource < Hyrax::Work; end
context 'with a valkyrie class' do
let(:obj) { SomeValkyrieResource }
it 'returns true' do
expect(described_class.use_valkyrie?(obj)).to be true
end
end

context 'with a valkyrie instance' do
let(:obj) { SomeValkyrieResource.new }
it 'returns true' do
expect(described_class.use_valkyrie?(obj)).to be true
end
end
end

context 'with active fedora' do
class SomeAfWork < ActiveFedora::Base; end
context 'with an af class' do
let(:obj) { SomeAfWork }
it 'returns false' do
expect(described_class.use_valkyrie?(obj)).to be false
end
end

context 'with an af instance' do
let(:obj) { SomeAfWork.new }
it 'returns false' do
expect(described_class.use_valkyrie?(obj)).to be false
end
end
end
end

context 'with customized .skip_splitting_pdf_files_that_end_with_these_texts' do
subject { described_class.split_for_path_suffix?(path, skip_these_endings: ['.READER.pdf']) }
[
Expand Down

0 comments on commit 5ab4c2a

Please sign in to comment.