Skip to content

Commit

Permalink
Merge pull request #5 from samvera-labs/ranges
Browse files Browse the repository at this point in the history
Add support for Structural Metadata.
  • Loading branch information
jcoyne authored Aug 2, 2017
2 parents 1e2167d + e46d3f5 commit 35f2f17
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ RSpec/VerifiedDoubles:
Exclude:
- 'spec/lib/iiif_manifest/display_image_spec.rb'

RSpec/ExampleLength:
Exclude:
- 'spec/lib/iiif_manifest/manifest_factory_spec.rb'

# Offense count: 20
Style/Documentation:
Exclude:
Expand All @@ -56,6 +60,7 @@ Style/Documentation:
- 'lib/iiif_manifest/manifest_builder/record_property_builder.rb'
- 'lib/iiif_manifest/manifest_builder/resource_builder.rb'
- 'lib/iiif_manifest/manifest_builder/sequence_builder.rb'
- 'lib/iiif_manifest/manifest_builder/structure_builder.rb'
- 'lib/iiif_manifest/manifest_builder.rb'
- 'lib/iiif_manifest/manifest_factory.rb'
- 'lib/iiif_manifest/manifest_service_locator.rb'
Expand All @@ -67,6 +72,10 @@ Style/MethodMissing:
Exclude:
- 'lib/iiif_manifest/manifest_builder/composite_builder.rb'

Metrics/ClassLength:
Exclude:
- 'lib/iiif_manifest/manifest_service_locator.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: MinSize, SupportedStyles.
Expand Down
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ Additionally, it ***must*** have a `#description` method that returns a string.

Additionally it ***should*** implement `#manifest_url` that shows where the manifest can be found.

Finally, it ***may*** implement `#sequence_rendering` to contain an array of hashes for file downloads to be offered at sequences level. Each hash must contain "@id", "format" (mime type) and "label" (eg. `{ "@id" => "download url", "format" => "application/pdf", "label" => "user friendly label" }`).
Additionally it ***may*** implement `#sequence_rendering` to contain an array of hashes for file downloads to be offered at sequences level. Each hash must contain "@id", "format" (mime type) and "label" (eg. `{ "@id" => "download url", "format" => "application/pdf", "label" => "user friendly label" }`).

Finally, It ***may*** implement `ranges`, which returns an array of objects which
represent a table of contents or similar structure, each of which responds to
`label`, `ranges`, and `file_set_presenters`.


For example:

Expand All @@ -37,10 +42,33 @@ For example:
def description
'a brief description'
end

def sequence_rendering:
[{"@id" => "http://test.host/file_set/id/download", "format" => "application/pdf", "label" => "Download"}]
end

def ranges
[
ManifestRange.new(
label: "Table of Contents",
ranges: [
ManifestRange.new(
label: "Chapter 1",
file_set_presenters: @pages
)
]
)
]
end
end

class ManifestRange
attr_reader :label, :ranges, :file_set_presenters
def initialize(label:, ranges: [], file_set_presenters: [])
@label = label
@ranges = ranges
@file_set_presenters = file_set_presenters
end
end
```

Expand Down
1 change: 1 addition & 0 deletions iiif_manifest.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rspec', '~> 3.0'
spec.add_development_dependency 'rubocop'
spec.add_development_dependency 'rubocop-rspec'
spec.add_development_dependency 'pry-byebug'
end
1 change: 1 addition & 0 deletions lib/iiif_manifest/manifest_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require_relative 'manifest_builder/record_property_builder'
require_relative 'manifest_builder/resource_builder'
require_relative 'manifest_builder/sequence_builder'
require_relative 'manifest_builder/structure_builder'

module IIIFManifest
class ManifestBuilder
Expand Down
76 changes: 76 additions & 0 deletions lib/iiif_manifest/manifest_builder/structure_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module IIIFManifest
class ManifestBuilder
class StructureBuilder
attr_reader :record
def initialize(record)
@record = record
end

def apply(manifest)
top_ranges.each_with_index do |top_range|
manifest['structures'] ||= []
manifest['structures'] = RangeBuilder.new(top_range, record, true).apply(manifest['structures'])
end
manifest
end

def top_ranges
record.try(:ranges) || []
end
end
class RangeBuilder
attr_reader :record, :parent
delegate :file_set_presenters, to: :record
def initialize(record, parent, top = false)
@record = record
@parent = parent
@top = top
build_range
end

def path
"#{parent.manifest_url}/range/r#{index}"
end

def index
@index ||= SecureRandom.uuid
end

def apply(manifest)
manifest << range
sub_ranges.map do |sub_range|
manifest = sub_range.apply(manifest)
end
manifest
end

def build_range
range['@id'] = path
range['label'] = record.label
range['viewingHint'] = 'top' if top?
range['ranges'] = sub_ranges.map(&:path)
range['canvases'] = canvas_builders.map(&:path)
end

def sub_ranges
@sub_ranges ||= record.ranges.map do |sub_range|
RangeBuilder.new(sub_range, parent)
end
end

def canvas_builders
@canvas_builders ||= file_set_presenters.map do |file_set_presenter|
CanvasBuilder.new(file_set_presenter, parent)
end
end

def range
@range ||= IIIF::Presentation::Range.new
end

def top?
@top
end
end
end
end
5 changes: 5 additions & 0 deletions lib/iiif_manifest/manifest_service_locator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def manifest_builders
composite_builder_factory.new(
record_property_builder,
sequence_builder,
structure_builder,
composite_builder: composite_builder
)
end
Expand Down Expand Up @@ -82,6 +83,10 @@ def record_property_builder
ManifestBuilder::RecordPropertyBuilder
end

def structure_builder
ManifestBuilder::StructureBuilder
end

def sequence_builder
InjectedFactory.new(
ManifestBuilder::SequenceBuilder,
Expand Down
34 changes: 34 additions & 0 deletions spec/lib/iiif_manifest/manifest_factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@ def work_presenters
def manifest_url
"http://test.host/books/#{@id}/manifest"
end

def ranges
@ranges ||=
[
ManifestRange.new(label: 'Table of Contents', ranges: [
ManifestRange.new(label: 'Chapter 1', file_set_presenters: [])
])
]
end
end

class ManifestRange
attr_reader :label, :ranges, :file_set_presenters
def initialize(label:, ranges: [], file_set_presenters: [])
@label = label
@ranges = ranges
@file_set_presenters = file_set_presenters
end
end

class DisplayImagePresenter
Expand Down Expand Up @@ -74,6 +92,22 @@ def display_image
expect(IIIFManifest::ManifestBuilder::CanvasBuilder).to have_received(:new)
.exactly(1).times.with(file_presenter, anything)
end
it 'builds a structure if it can' do
allow(book_presenter).to receive(:file_set_presenters).and_return([file_presenter])
allow(book_presenter.ranges[0].ranges[0]).to receive(:file_set_presenters).and_return([file_presenter])

expect(result['structures'].length).to eq 2
structure = result['structures'].first
expect(structure['label']).to eq 'Table of Contents'
expect(structure['viewingHint']).to eq 'top'
expect(structure['canvases']).to be_blank
expect(structure['ranges'].length).to eq 1
expect(structure['ranges'][0]).not_to eq structure['@id']

sub_range = result['structures'].last
expect(sub_range['ranges']).to be_blank
expect(sub_range['canvases'].length).to eq 1
end
end

context 'where there is a no sequence_rendering method' do
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'iiif_manifest'
require 'pry'

0 comments on commit 35f2f17

Please sign in to comment.