Class: IiifPrint::PersistenceLayer::ValkyrieAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/iiif_print/persistence_layer/valkyrie_adapter.rb

Class Method Summary collapse

Methods inherited from AbstractAdapter

solr_field_query

Class Method Details

.clean_for_tests!Object

Raises:

  • (NotImplementedError)


75
76
77
78
79
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 75

def self.clean_for_tests!
  # For Fedora backed repositories, we'll want to consider some cleaning mechanism.  For
  # database backed repositories, we can rely on the database_cleaner gem.
  raise NotImplementedError
end

.copy_derivatives_from_data_store(stream:, directives:) ⇒ TrueClass

Performs an extra step to create the Hyrax::Metadata objects for derivatives.

Parameters:

  • []

Returns:

  • (TrueClass)


197
198
199
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 197

def self.copy_derivatives_from_data_store(stream:, directives:)
  Hyrax::ValkyriePersistDerivatives.call(stream, directives)
end

.create_relationship_between(child_record:, parent_record:) ⇒ TrueClass

Add a child record as a member of a parent record

Parameters:

  • model (child_record)

    a Valkyrie::Resource model

  • model (parent_record)

    a Valkyrie::Resource model

Returns:

  • (TrueClass)


136
137
138
139
140
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 136

def self.create_relationship_between(child_record:, parent_record:)
  return true if parent_record.member_ids.include?(child_record.id)
  parent_record.member_ids << child_record.id
  true
end

.decorate_form_with_adapter_logic(work_type:) ⇒ Object

Returns form for the given :work_type.

Parameters:

  • work_type (Class<ActiveFedora::Base>)

Returns:

  • form for the given :work_type



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 36

def self.decorate_form_with_adapter_logic(work_type:)
  # In Hyrax flexible metadata mode, `Hyrax::FormFields(:child_works_from_pdf_splitting)`
  # is a no-op but calling `"#{work_type}Form".constantize` unconditionally causes a
  # circular autoload error when a model is loaded before its form.
  return if Hyrax.config.try(:flexible?)

  form = "#{work_type}Form".constantize
  form.send(:include, Hyrax::FormFields(:child_works_from_pdf_splitting)) if
    Hyrax.config.try(:work_include_metadata?) && !form.included_modules.include?(Hyrax::FormFields(:child_works_from_pdf_splitting))
  form
end

.decorate_with_adapter_logic(work_type:) ⇒ Object

Returns the indexer for the given :work_type.

Parameters:

  • work_type (Class<Valkyrie::Resource>)

Returns:

  • the indexer for the given :work_type



23
24
25
26
27
28
29
30
31
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 23

def self.decorate_with_adapter_logic(work_type:)
  work_type.send(:include, Hyrax::Schema(:child_works_from_pdf_splitting)) if
    Hyrax.config.try(:work_include_metadata?) && !Hyrax.config.try(:flexible?) && !work_type.included_modules.include?(Hyrax::FormFields(:child_works_from_pdf_splitting))
  # TODO: Use `Hyrax::ValkyrieIndexer.indexer_class_for` once changes are merged.
  indexer = "#{work_type}Indexer".constantize
  indexer.send(:include, Hyrax::Indexer(:child_works_from_pdf_splitting)) if
    Hyrax.config.try(:work_include_metadata?) && !Hyrax.config.try(:flexible?) && !indexer.included_modules.include?(Hyrax::FormFields(:child_works_from_pdf_splitting))
  indexer
end

.destroy_children_split_from(file_set:, work:, model:, user:) ⇒ Object

NOTE: this isn’t the most efficient method, but it is the most reliable.

Attribute 'split_from_pdf_id' is saved in Valkyrie as a string rather than as { id: string },
  so we can't use the 'find_inverse_references_by' query.
Additionally, the attribute does not exist on all child works, as it was added later, so using
  a child work's title allows us to find child works when the attribute isn't present.
Building a custom query to find these child works directly via the attribute would be more efficient.
  However, it would require more effort for a lesser-used feature, and would not allow for the fallback
  of finding child works by title.

rubocop:disable Lint/UnusedMethodArgument, Metrics/AbcSize, Metrics/MethodLength



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 98

def self.destroy_children_split_from(file_set:, work:, model:, user:)
  all_child_works = Hyrax.custom_queries.find_child_works(resource: work)
  return if all_child_works.blank?
  # look first for children by the file set id they were split from
  children = all_child_works.select { |m| m.split_from_pdf_id == file_set.id }
  if children.blank?
    # find works where file name and work `to_param` are both in the title
    children = all_child_works.select { |m| m.title.include?(file_set.label) && m.title.include?(work.to_param) }
  end
  return if children.blank?
  # we have to update the work's members first, then delete the children
  # otherwise Hyrax tries to save the parent as each child is deleted, resulting
  # in failing jobs
  remaining_members = work.member_ids - children.map(&:id)
  work.member_ids = remaining_members
  Hyrax.persister.save(resource: work)
  Hyrax.index_adapter.save(resource: work)
  Hyrax.publisher.publish('object.membership.updated', object: work, user: user)

  children.each do |rcd|
    Hyrax.persister.delete(resource: rcd)
    Hyrax.index_adapter.delete(resource: rcd)
    Hyrax.publisher.publish('object.deleted', object: rcd, user: user)
  end
  true
end

.extract_text_for(file_set:) ⇒ String

Extract text from the derivatives

Parameters:

  • a (Hyrax::FileSet)

    Valkyrie fileset

Returns:

  • (String)

    Text from fileset’s file



206
207
208
209
210
211
212
213
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 206

def self.extract_text_for(file_set:)
  fm = Hyrax.custom_queries.(resource: file_set,
  use: Hyrax::FileMetadata::Use.uri_for(use: :extracted_file))
  return if fm.empty?
  text_fm = fm.find { |t| t.mime_type == Marcel::MimeType.for(extension: 'txt') }
  return if text_fm.nil?
  text_fm.content
end

.find_by(id:) ⇒ Object

find a work or file_set

Parameters:

  • id (String)


161
162
163
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 161

def self.find_by(id:)
  Hyrax.query_service.find_by(id: id)
end

.find_by_title_for(title:, model:) ⇒ Array<Valkyrie::Resource]

find a work by title We should only find one, but there is no guarantee of that

Parameters:

  • title (String)
  • model (String)

    a Valkyrie::Resource model

Returns:

  • (Array<Valkyrie::Resource])

    Array<Valkyrie::Resource]



148
149
150
151
152
153
154
155
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 148

def self.find_by_title_for(title:, model:)
  work_type = model.constantize
  # TODO: This creates a hard dependency on Bulkrax because that is where this custom query is defined
  #       Is this adequate?
  Array.wrap(Hyrax.query_service.custom_query.find_by_model_and_property_value(model: work_type,
                                                                               property: :title,
                                                                               value: title))
end

.grandparent_for(file_set) ⇒ #work?, ...

Return the parent’s parent of the given :file_set.

Parameters:

  • file_set (Hyrax::FileMetadata or FileSet)

Returns:

  • (#work?, Hydra::PCDM::Work)
  • (NilClass)

    when no grand parent is found.



65
66
67
68
69
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 65

def self.grandparent_for(file_set)
  parent = parent_for(file_set)
  return nil unless parent
  Hyrax.query_service.find_parents(resource: parent).first
end

.index_works(objects:) ⇒ TrueClass

reindex an array of works and their file_sets

Parameters:

  • objects (Array<Valkyrie::Resource])

    bjects [Array<Valkyrie::Resource]

Returns:

  • (TrueClass)


181
182
183
184
185
186
187
188
189
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 181

def self.index_works(objects:)
  objects.each do |work|
    Hyrax.index_adapter.save(resource: work)
    Hyrax.custom_queries.find_child_file_sets(resource: work).each do |file_set|
      Hyrax.index_adapter.save(resource: file_set)
    end
  end
  true
end

.object_in_works(object) ⇒ Array<Valkyrie::Resource>

Parameters:

  • object (Valkyrie::Resource)

Returns:

  • (Array<Valkyrie::Resource>)


9
10
11
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 9

def self.object_in_works(object)
  Array.wrap(Hyrax.custom_queries.find_parent_work(resource: object))
end

.object_ordered_works(object) ⇒ Array<Valkyrie::Resource>

Parameters:

  • object (Valkyrie::Resource)

Returns:

  • (Array<Valkyrie::Resource>)


16
17
18
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 16

def self.object_ordered_works(object)
  Hyrax.custom_queries.find_child_works(resource: object).to_a
end

.parent_for(file_set) ⇒ #work?, ...

Return the immediate parent of the given :file_set.

Parameters:

  • file_set (Hyrax::FileMetadata or FileSet)

Returns:

  • (#work?, Hydra::PCDM::Work)
  • (NilClass)

    when no parent is found.



54
55
56
57
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 54

def self.parent_for(file_set)
  file_set = Hyrax.query_service.find_by(id: file_set.file_set_id) if file_set.is_a?(Hyrax::FileMetadata)
  Hyrax.query_service.find_parents(resource: file_set).first
end

.pdf?(file_set) ⇒ Boolean

rubocop:enable Lint/UnusedMethodArgument, Metrics/AbcSize, Metrics/MethodLength

Returns:

  • (Boolean)


126
127
128
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 126

def self.pdf?(file_set)
  file_set.original_file&.pdf?
end

.pdf_path_for(file_set:) ⇒ String

Location of the file for resplitting

Parameters:

  • a (Hyrax::FileSet)

    Valkyrie fileset

Returns:

  • (String)

    location of the original file



220
221
222
223
224
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 220

def self.pdf_path_for(file_set:)
  file = file_set.original_file
  return '' unless file.pdf?
  file.file.disk_path.to_s
end

.save(object:) ⇒ Object

save a work

Parameters:

  • object (Array<Valkyrie::Resource])

    bject [Array<Valkyrie::Resource]



169
170
171
172
173
174
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 169

def self.save(object:)
  Hyrax.persister.save(resource: object)
  Hyrax.index_adapter.save(resource: object)

  Hyrax.publisher.publish('object.membership.updated', object: object, user: object.depositor)
end

.solr_construct_query(*args) ⇒ Object



71
72
73
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 71

def self.solr_construct_query(*args)
  Hyrax::SolrQueryBuilderService.construct_query(*args)
end

.solr_name(field_name) ⇒ Object



85
86
87
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 85

def self.solr_name(field_name)
  Hyrax.config.index_field_mapper.solr_name(field_name.to_s)
end

.solr_query(query, **args) ⇒ Object



81
82
83
# File 'lib/iiif_print/persistence_layer/valkyrie_adapter.rb', line 81

def self.solr_query(query, **args)
  Hyrax::SolrService.query(query, **args)
end