iiif_manifest 0.2.0 → 0.3.0
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/.gitignore +0 -0
- data/.rspec +0 -0
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +84 -0
- data/.travis.yml +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/README.md +48 -2
- data/Rakefile +12 -3
- data/bin/console +3 -3
- data/iiif_manifest.gemspec +17 -15
- data/lib/iiif_manifest/display_image.rb +0 -0
- data/lib/iiif_manifest/iiif_collection.rb +1 -0
- data/lib/iiif_manifest/iiif_endpoint.rb +1 -1
- data/lib/iiif_manifest/manifest_builder/canvas_builder.rb +15 -13
- data/lib/iiif_manifest/manifest_builder/canvas_builder_factory.rb +3 -3
- data/lib/iiif_manifest/manifest_builder/child_manifest_builder_factory.rb +0 -0
- data/lib/iiif_manifest/manifest_builder/composite_builder.rb +0 -0
- data/lib/iiif_manifest/manifest_builder/composite_builder_factory.rb +0 -0
- data/lib/iiif_manifest/manifest_builder/deep_canvas_builder_factory.rb +6 -6
- data/lib/iiif_manifest/manifest_builder/image_builder.rb +14 -12
- data/lib/iiif_manifest/manifest_builder/image_service_builder.rb +6 -5
- data/lib/iiif_manifest/manifest_builder/record_property_builder.rb +28 -11
- data/lib/iiif_manifest/manifest_builder/resource_builder.rb +13 -11
- data/lib/iiif_manifest/manifest_builder/sequence_builder.rb +23 -13
- data/lib/iiif_manifest/manifest_builder/structure_builder.rb +94 -0
- data/lib/iiif_manifest/manifest_builder.rb +9 -8
- data/lib/iiif_manifest/manifest_factory.rb +0 -0
- data/lib/iiif_manifest/manifest_service_locator.rb +65 -3
- data/lib/iiif_manifest/version.rb +1 -1
- data/lib/iiif_manifest.rb +1 -1
- metadata +48 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bf49dd68d7cea2339444aafd8eb4f98ac3cdcd9
|
4
|
+
data.tar.gz: ddee2270d2cf0f5098c40ecee97fd696a59a36f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef3820b328e75af3da30aee55bafd526ae0d6ae7c7533cc53bf0ae743d61d83cf027cca5048a70460a02eb39103c94c2e03e900be19ffe29b57e3cee3b61b4bc
|
7
|
+
data.tar.gz: 5c948e5dc59e0926ce983c9ba6445d4f7011f342eae3bd18cff854a5183687affb78e396e2498c54f8be240268b6774d415be69ec38fa77fe2526df8f2916908
|
data/.gitignore
CHANGED
File without changes
|
data/.rspec
CHANGED
File without changes
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-07-26 10:46:37 -0500 using RuboCop version 0.49.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Exclude:
|
12
|
+
- 'lib/iiif_manifest/manifest_builder/resource_builder.rb'
|
13
|
+
- 'lib/iiif_manifest/manifest_factory.rb'
|
14
|
+
|
15
|
+
# Offense count: 1
|
16
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
17
|
+
# URISchemes: http, https
|
18
|
+
Metrics/LineLength:
|
19
|
+
Exclude:
|
20
|
+
- 'iiif_manifest.gemspec'
|
21
|
+
|
22
|
+
# Offense count: 1
|
23
|
+
# Configuration parameters: AssignmentOnly.
|
24
|
+
RSpec/InstanceVariable:
|
25
|
+
Exclude:
|
26
|
+
- 'spec/lib/iiif_manifest/manifest_factory_spec.rb'
|
27
|
+
|
28
|
+
# Offense count: 8
|
29
|
+
RSpec/NamedSubject:
|
30
|
+
Exclude:
|
31
|
+
- 'spec/lib/iiif_manifest/display_image_spec.rb'
|
32
|
+
- 'spec/lib/iiif_manifest/iiif_endpoint_spec.rb'
|
33
|
+
- 'spec/lib/iiif_manifest/manifest_builder/resource_builder_spec.rb'
|
34
|
+
|
35
|
+
# Offense count: 1
|
36
|
+
# Configuration parameters: IgnoreSymbolicNames.
|
37
|
+
RSpec/VerifiedDoubles:
|
38
|
+
Exclude:
|
39
|
+
- 'spec/lib/iiif_manifest/display_image_spec.rb'
|
40
|
+
|
41
|
+
RSpec/ExampleLength:
|
42
|
+
Exclude:
|
43
|
+
- 'spec/lib/iiif_manifest/manifest_factory_spec.rb'
|
44
|
+
|
45
|
+
# Offense count: 20
|
46
|
+
Style/Documentation:
|
47
|
+
Exclude:
|
48
|
+
- 'lib/iiif_manifest/display_image.rb'
|
49
|
+
- 'lib/iiif_manifest/iiif_collection.rb'
|
50
|
+
- 'lib/iiif_manifest/iiif_endpoint.rb'
|
51
|
+
- 'lib/iiif_manifest/manifest_builder/canvas_builder.rb'
|
52
|
+
- 'lib/iiif_manifest/manifest_builder/canvas_builder.rb'
|
53
|
+
- 'lib/iiif_manifest/manifest_builder/canvas_builder_factory.rb'
|
54
|
+
- 'lib/iiif_manifest/manifest_builder/child_manifest_builder_factory.rb'
|
55
|
+
- 'lib/iiif_manifest/manifest_builder/composite_builder.rb'
|
56
|
+
- 'lib/iiif_manifest/manifest_builder/composite_builder_factory.rb'
|
57
|
+
- 'lib/iiif_manifest/manifest_builder/deep_canvas_builder_factory.rb'
|
58
|
+
- 'lib/iiif_manifest/manifest_builder/image_builder.rb'
|
59
|
+
- 'lib/iiif_manifest/manifest_builder/image_service_builder.rb'
|
60
|
+
- 'lib/iiif_manifest/manifest_builder/record_property_builder.rb'
|
61
|
+
- 'lib/iiif_manifest/manifest_builder/resource_builder.rb'
|
62
|
+
- 'lib/iiif_manifest/manifest_builder/sequence_builder.rb'
|
63
|
+
- 'lib/iiif_manifest/manifest_builder/structure_builder.rb'
|
64
|
+
- 'lib/iiif_manifest/manifest_builder.rb'
|
65
|
+
- 'lib/iiif_manifest/manifest_factory.rb'
|
66
|
+
- 'lib/iiif_manifest/manifest_service_locator.rb'
|
67
|
+
- 'lib/iiif_manifest.rb'
|
68
|
+
- 'spec/lib/iiif_manifest/manifest_factory_spec.rb'
|
69
|
+
|
70
|
+
# Offense count: 1
|
71
|
+
Style/MethodMissing:
|
72
|
+
Exclude:
|
73
|
+
- 'lib/iiif_manifest/manifest_builder/composite_builder.rb'
|
74
|
+
|
75
|
+
Metrics/ClassLength:
|
76
|
+
Exclude:
|
77
|
+
- 'lib/iiif_manifest/manifest_service_locator.rb'
|
78
|
+
|
79
|
+
# Offense count: 1
|
80
|
+
# Cop supports --auto-correct.
|
81
|
+
# Configuration parameters: MinSize, SupportedStyles.
|
82
|
+
# SupportedStyles: percent, brackets
|
83
|
+
Style/SymbolArray:
|
84
|
+
EnforcedStyle: brackets
|
data/.travis.yml
CHANGED
File without changes
|
data/CODE_OF_CONDUCT.md
CHANGED
File without changes
|
data/Gemfile
CHANGED
File without changes
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -5,11 +5,23 @@ IIIF http://iiif.io/ defines an API for presenting related images in a viewer. T
|
|
5
5
|
|
6
6
|
## Usage
|
7
7
|
|
8
|
-
|
8
|
+
Your application ***must*** have an object that implements `#file_set_presenters` and `#work_presenters`. The former method should return as set of leaf nodes and the later any interstitial nodes. If none are found an empty array should be returned.
|
9
|
+
|
10
|
+
Additionally, it ***must*** have a `#description` method that returns a string.
|
11
|
+
|
12
|
+
Additionally it ***should*** implement `#manifest_url` that shows where the manifest can be found.
|
13
|
+
|
14
|
+
Additionally it ***should*** implement `#manifest_metadata` to provide an array containing hashes of metadata Label/Value pairs.
|
15
|
+
|
16
|
+
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" }`).
|
17
|
+
|
18
|
+
Finally, It ***may*** implement `ranges`, which returns an array of objects which
|
19
|
+
represent a table of contents or similar structure, each of which responds to
|
20
|
+
`label`, `ranges`, and `file_set_presenters`.
|
9
21
|
|
10
22
|
For example:
|
11
23
|
|
12
|
-
```ruby
|
24
|
+
```ruby
|
13
25
|
class Book
|
14
26
|
def initialize(id, pages = [])
|
15
27
|
@id = id
|
@@ -31,6 +43,40 @@ For example:
|
|
31
43
|
def description
|
32
44
|
'a brief description'
|
33
45
|
end
|
46
|
+
|
47
|
+
def manifest_metadata
|
48
|
+
[
|
49
|
+
{ "label" => "Title", "value" => "Title of the Item" },
|
50
|
+
{ "label" => "Creator", "value" => "Morrissey, Stephen Patrick" }
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
def sequence_rendering
|
55
|
+
[{"@id" => "http://test.host/file_set/id/download", "format" => "application/pdf", "label" => "Download"}]
|
56
|
+
end
|
57
|
+
|
58
|
+
def ranges
|
59
|
+
[
|
60
|
+
ManifestRange.new(
|
61
|
+
label: "Table of Contents",
|
62
|
+
ranges: [
|
63
|
+
ManifestRange.new(
|
64
|
+
label: "Chapter 1",
|
65
|
+
file_set_presenters: @pages
|
66
|
+
)
|
67
|
+
]
|
68
|
+
)
|
69
|
+
]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ManifestRange
|
74
|
+
attr_reader :label, :ranges, :file_set_presenters
|
75
|
+
def initialize(label:, ranges: [], file_set_presenters: [])
|
76
|
+
@label = label
|
77
|
+
@ranges = ranges
|
78
|
+
@file_set_presenters = file_set_presenters
|
79
|
+
end
|
34
80
|
end
|
35
81
|
```
|
36
82
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
|
-
|
7
|
+
desc 'Run style checker'
|
8
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
9
|
+
task.fail_on_error = true
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Run all checks'
|
13
|
+
task ci: [:rubocop, :spec]
|
14
|
+
|
15
|
+
task default: :ci
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'iiif_manifest'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "iiif_manifest"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start
|
data/iiif_manifest.gemspec
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'iiif_manifest/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'iiif_manifest'
|
8
7
|
spec.version = IIIFManifest::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['Justin Coyne', 'Trey Pendragon']
|
9
|
+
spec.email = ['jcoyne@justincoyne.com']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
11
|
+
spec.summary = 'Generate IIIF presentation manifests for Hydra::Works'
|
12
|
+
spec.description = 'IIIF http://iiif.io/ defines an API for presenting related images in a viewer. This transforms Hydra::Works objects into that format usable by players such as http://universalviewer.io/'
|
13
|
+
spec.homepage = 'http://github.com/projecthydra-labs/iiif_manifest'
|
15
14
|
|
16
15
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir =
|
16
|
+
spec.bindir = 'exe'
|
18
17
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
20
|
+
spec.add_dependency 'activesupport', '>= 4'
|
21
|
+
spec.add_dependency 'iiif-presentation', '~> 0.2.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'rubocop'
|
27
|
+
spec.add_development_dependency 'rubocop-rspec'
|
28
|
+
spec.add_development_dependency 'pry-byebug'
|
27
29
|
end
|
File without changes
|
@@ -1,17 +1,19 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class CanvasBuilder
|
4
|
-
attr_reader :record, :parent
|
4
|
+
attr_reader :record, :parent, :iiif_canvas_factory, :image_builder
|
5
5
|
|
6
|
-
def initialize(record, parent)
|
6
|
+
def initialize(record, parent, iiif_canvas_factory:, image_builder:)
|
7
7
|
@record = record
|
8
8
|
@parent = parent
|
9
|
+
@iiif_canvas_factory = iiif_canvas_factory
|
10
|
+
@image_builder = image_builder
|
9
11
|
apply_record_properties
|
10
12
|
attach_image if display_image
|
11
13
|
end
|
12
14
|
|
13
15
|
def canvas
|
14
|
-
@canvas ||=
|
16
|
+
@canvas ||= iiif_canvas_factory.new
|
15
17
|
end
|
16
18
|
|
17
19
|
def path
|
@@ -26,18 +28,18 @@ module IIIFManifest
|
|
26
28
|
|
27
29
|
private
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def display_image
|
32
|
+
record.display_image if record.respond_to?(:display_image)
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def apply_record_properties
|
36
|
+
canvas['@id'] = path
|
37
|
+
canvas.label = record.to_s
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
def attach_image
|
41
|
+
image_builder.new(display_image).apply(canvas)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -26,13 +26,13 @@ module IIIFManifest
|
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def file_set_presenters
|
30
|
+
work.try(:file_set_presenters) || []
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def work_presenters
|
34
|
+
work.try(:work_presenters) || []
|
35
|
+
end
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class ImageBuilder
|
4
|
-
attr_reader :display_image
|
5
|
-
def initialize(display_image)
|
4
|
+
attr_reader :display_image, :iiif_annotation_factory, :resource_builder_factory
|
5
|
+
def initialize(display_image, iiif_annotation_factory:, resource_builder_factory:)
|
6
6
|
@display_image = display_image
|
7
|
+
@iiif_annotation_factory = iiif_annotation_factory
|
8
|
+
@resource_builder_factory = resource_builder_factory
|
7
9
|
build_resource
|
8
10
|
end
|
9
11
|
|
@@ -11,22 +13,22 @@ module IIIFManifest
|
|
11
13
|
annotation['on'] = canvas['@id']
|
12
14
|
canvas['width'] = annotation.resource['width']
|
13
15
|
canvas['height'] = annotation.resource['height']
|
14
|
-
canvas.images
|
16
|
+
canvas.images += [annotation]
|
15
17
|
end
|
16
18
|
|
17
19
|
private
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
def build_resource
|
22
|
+
resource_builder.apply(annotation)
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
def resource_builder
|
26
|
+
resource_builder_factory.new(display_image)
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
def annotation
|
30
|
+
@annotation ||= iiif_annotation_factory.new
|
31
|
+
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class ImageServiceBuilder
|
4
|
-
attr_reader :iiif_endpoint
|
5
|
-
def initialize(iiif_endpoint)
|
4
|
+
attr_reader :iiif_endpoint, :iiif_service_factory
|
5
|
+
def initialize(iiif_endpoint, iiif_service_factory:)
|
6
6
|
@iiif_endpoint = iiif_endpoint
|
7
|
+
@iiif_service_factory = iiif_service_factory
|
7
8
|
end
|
8
9
|
|
9
10
|
def apply(resource)
|
@@ -15,9 +16,9 @@ module IIIFManifest
|
|
15
16
|
|
16
17
|
private
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def service
|
20
|
+
@service ||= iiif_service_factory.new
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -10,24 +10,41 @@ module IIIFManifest
|
|
10
10
|
manifest['@id'] = record.manifest_url.to_s
|
11
11
|
manifest.label = record.to_s
|
12
12
|
manifest.description = record.description
|
13
|
-
manifest.viewing_hint = viewing_hint
|
13
|
+
manifest.viewing_hint = viewing_hint if viewing_hint.present?
|
14
|
+
manifest.metadata = record.manifest_metadata if valid_metadata?
|
14
15
|
manifest
|
15
|
-
# manifest.try(:viewing_direction=, viewing_direction)
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def viewing_hint
|
21
|
+
(record.respond_to?(:viewing_hint) && record.send(:viewing_hint))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Validate manifest_metadata against the IIIF spec format for metadata
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
def valid_metadata?
|
28
|
+
return false unless record.respond_to?(:manifest_metadata)
|
29
|
+
metadata = record.manifest_metadata
|
30
|
+
valid_metadata_structure?(metadata) && valid_metadata_content?(metadata)
|
31
|
+
end
|
23
32
|
|
24
|
-
#
|
25
|
-
# record.try(:viewing_direction) || "left-to-right"
|
26
|
-
# end
|
33
|
+
# Manifest metadata must be an array containing hashes
|
27
34
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
35
|
+
# @param metadata [Array<Hash>] a list of metadata with label and value as required keys for each entry
|
36
|
+
# @return [Boolean]
|
37
|
+
def valid_metadata_structure?(metadata)
|
38
|
+
metadata.is_a?(Array) && metadata.all? { |v| v.is_a?(Hash) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Manifest Metadata Hashes must contain 'label' and 'value' keys
|
42
|
+
#
|
43
|
+
# @param metadata [Array<Hash>] a list of metadata with label and value as required keys for each entry
|
44
|
+
# @return [Boolean]
|
45
|
+
def valid_metadata_content?(metadata)
|
46
|
+
metadata.all? { |v| v['label'].present? && v['value'].present? }
|
47
|
+
end
|
31
48
|
end
|
32
49
|
end
|
33
50
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class ResourceBuilder
|
4
|
-
attr_reader :display_image
|
5
|
-
def initialize(display_image)
|
4
|
+
attr_reader :display_image, :iiif_resource_factory, :image_service_builder_factory
|
5
|
+
def initialize(display_image, iiif_resource_factory:, image_service_builder_factory:)
|
6
6
|
@display_image = display_image
|
7
|
+
@iiif_resource_factory = iiif_resource_factory
|
8
|
+
@image_service_builder_factory = image_service_builder_factory
|
7
9
|
end
|
8
10
|
|
9
11
|
def apply(annotation)
|
@@ -18,17 +20,17 @@ module IIIFManifest
|
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
def resource
|
24
|
+
@resource ||= iiif_resource_factory.new
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def iiif_endpoint
|
28
|
+
display_image.try(:iiif_endpoint)
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def image_service_builder
|
32
|
+
image_service_builder_factory.new(iiif_endpoint)
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class SequenceBuilder
|
4
|
-
attr_reader :work, :canvas_builder_factory
|
5
|
-
def initialize(work, canvas_builder_factory:)
|
4
|
+
attr_reader :work, :canvas_builder_factory, :sequence_factory
|
5
|
+
def initialize(work, canvas_builder_factory:, sequence_factory:)
|
6
6
|
@work = work
|
7
7
|
@canvas_builder_factory = canvas_builder_factory
|
8
|
+
@sequence_factory = sequence_factory
|
8
9
|
end
|
9
10
|
|
10
11
|
def apply(manifest)
|
@@ -19,19 +20,28 @@ module IIIFManifest
|
|
19
20
|
|
20
21
|
private
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
def canvas_builder
|
24
|
+
canvas_builder_factory.from(work)
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def sequence
|
28
|
+
@sequence ||=
|
29
|
+
begin
|
30
|
+
sequence = sequence_factory.new
|
31
|
+
sequence['@id'] ||= work.manifest_url + '/sequence/normal'
|
32
|
+
sequence['rendering'] ||= populate_sequence_rendering
|
33
|
+
canvas_builder.apply(sequence)
|
34
|
+
sequence
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def populate_sequence_rendering
|
39
|
+
if work.respond_to?(:sequence_rendering)
|
40
|
+
work.sequence_rendering.each(&:to_h)
|
41
|
+
else
|
42
|
+
[]
|
34
43
|
end
|
44
|
+
end
|
35
45
|
end
|
36
46
|
end
|
37
47
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module IIIFManifest
|
2
|
+
class ManifestBuilder
|
3
|
+
class StructureBuilder
|
4
|
+
attr_reader :record, :canvas_builder_factory, :iiif_range_factory
|
5
|
+
def initialize(record, canvas_builder_factory:, iiif_range_factory:)
|
6
|
+
@record = record
|
7
|
+
@canvas_builder_factory = canvas_builder_factory
|
8
|
+
@iiif_range_factory = iiif_range_factory
|
9
|
+
end
|
10
|
+
|
11
|
+
def apply(manifest)
|
12
|
+
top_ranges.each do |top_range|
|
13
|
+
manifest['structures'] ||= []
|
14
|
+
manifest['structures'] = range_builder(top_range).apply(manifest['structures'])
|
15
|
+
end
|
16
|
+
manifest
|
17
|
+
end
|
18
|
+
|
19
|
+
def range_builder(top_range)
|
20
|
+
RangeBuilder.new(
|
21
|
+
top_range,
|
22
|
+
record, true,
|
23
|
+
canvas_builder_factory: canvas_builder_factory,
|
24
|
+
iiif_range_factory: iiif_range_factory
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def top_ranges
|
29
|
+
record.try(:ranges) || []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
class RangeBuilder
|
33
|
+
attr_reader :record, :parent, :canvas_builder_factory, :iiif_range_factory
|
34
|
+
delegate :file_set_presenters, to: :record
|
35
|
+
def initialize(record, parent, top = false, canvas_builder_factory:, iiif_range_factory:)
|
36
|
+
@record = record
|
37
|
+
@parent = parent
|
38
|
+
@top = top
|
39
|
+
@canvas_builder_factory = canvas_builder_factory
|
40
|
+
@iiif_range_factory = iiif_range_factory
|
41
|
+
build_range
|
42
|
+
end
|
43
|
+
|
44
|
+
def path
|
45
|
+
"#{parent.manifest_url}/range/r#{index}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def index
|
49
|
+
@index ||= SecureRandom.uuid
|
50
|
+
end
|
51
|
+
|
52
|
+
def apply(manifest)
|
53
|
+
manifest << range
|
54
|
+
sub_ranges.map do |sub_range|
|
55
|
+
manifest = sub_range.apply(manifest)
|
56
|
+
end
|
57
|
+
manifest
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_range
|
61
|
+
range['@id'] = path
|
62
|
+
range['label'] = record.label
|
63
|
+
range['viewingHint'] = 'top' if top?
|
64
|
+
range['ranges'] = sub_ranges.map(&:path)
|
65
|
+
range['canvases'] = canvas_builders.map(&:path)
|
66
|
+
end
|
67
|
+
|
68
|
+
def sub_ranges
|
69
|
+
@sub_ranges ||= record.ranges.map do |sub_range|
|
70
|
+
RangeBuilder.new(
|
71
|
+
sub_range,
|
72
|
+
parent,
|
73
|
+
canvas_builder_factory: canvas_builder_factory,
|
74
|
+
iiif_range_factory: iiif_range_factory
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def canvas_builders
|
80
|
+
@canvas_builders ||= file_set_presenters.map do |file_set_presenter|
|
81
|
+
canvas_builder_factory.new(file_set_presenter, parent)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def range
|
86
|
+
@range ||= iiif_range_factory.new
|
87
|
+
end
|
88
|
+
|
89
|
+
def top?
|
90
|
+
@top
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -9,6 +9,7 @@ require_relative 'manifest_builder/image_service_builder'
|
|
9
9
|
require_relative 'manifest_builder/record_property_builder'
|
10
10
|
require_relative 'manifest_builder/resource_builder'
|
11
11
|
require_relative 'manifest_builder/sequence_builder'
|
12
|
+
require_relative 'manifest_builder/structure_builder'
|
12
13
|
|
13
14
|
module IIIFManifest
|
14
15
|
class ManifestBuilder
|
@@ -22,8 +23,8 @@ module IIIFManifest
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def apply(collection)
|
25
|
-
collection[
|
26
|
-
collection[
|
26
|
+
collection['manifests'] ||= []
|
27
|
+
collection['manifests'] << to_h
|
27
28
|
collection
|
28
29
|
end
|
29
30
|
|
@@ -33,12 +34,12 @@ module IIIFManifest
|
|
33
34
|
|
34
35
|
private
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
def manifest
|
38
|
+
@manifest ||= manifest_builder_class
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
def top_record
|
42
|
+
top_record_factory.new
|
43
|
+
end
|
43
44
|
end
|
44
45
|
end
|
File without changes
|
@@ -39,6 +39,7 @@ module IIIFManifest
|
|
39
39
|
composite_builder_factory.new(
|
40
40
|
record_property_builder,
|
41
41
|
sequence_builder,
|
42
|
+
structure_builder,
|
42
43
|
composite_builder: composite_builder
|
43
44
|
)
|
44
45
|
end
|
@@ -82,20 +83,34 @@ module IIIFManifest
|
|
82
83
|
ManifestBuilder::RecordPropertyBuilder
|
83
84
|
end
|
84
85
|
|
86
|
+
def structure_builder
|
87
|
+
InjectedFactory.new(
|
88
|
+
ManifestBuilder::StructureBuilder,
|
89
|
+
canvas_builder_factory: canvas_builder,
|
90
|
+
iiif_range_factory: iiif_range_factory
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
85
94
|
def sequence_builder
|
86
95
|
InjectedFactory.new(
|
87
96
|
ManifestBuilder::SequenceBuilder,
|
88
|
-
canvas_builder_factory: canvas_builder_factory
|
97
|
+
canvas_builder_factory: canvas_builder_factory,
|
98
|
+
sequence_factory: sequence_factory
|
89
99
|
)
|
90
100
|
end
|
91
101
|
|
92
102
|
def sammelband_sequence_builder
|
93
103
|
InjectedFactory.new(
|
94
104
|
ManifestBuilder::SequenceBuilder,
|
95
|
-
canvas_builder_factory: deep_canvas_builder_factory
|
105
|
+
canvas_builder_factory: deep_canvas_builder_factory,
|
106
|
+
sequence_factory: sequence_factory
|
96
107
|
)
|
97
108
|
end
|
98
109
|
|
110
|
+
def sequence_factory
|
111
|
+
IIIF::Presentation::Sequence
|
112
|
+
end
|
113
|
+
|
99
114
|
def canvas_builder_factory
|
100
115
|
ManifestBuilder::CanvasBuilderFactory.new(
|
101
116
|
composite_builder: composite_builder,
|
@@ -111,12 +126,59 @@ module IIIFManifest
|
|
111
126
|
end
|
112
127
|
|
113
128
|
def canvas_builder
|
114
|
-
|
129
|
+
InjectedFactory.new(
|
130
|
+
ManifestBuilder::CanvasBuilder,
|
131
|
+
iiif_canvas_factory: iiif_canvas_factory,
|
132
|
+
image_builder: image_builder
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
def image_builder
|
137
|
+
InjectedFactory.new(
|
138
|
+
ManifestBuilder::ImageBuilder,
|
139
|
+
iiif_annotation_factory: iiif_annotation_factory,
|
140
|
+
resource_builder_factory: resource_builder_factory
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def resource_builder_factory
|
145
|
+
InjectedFactory.new(
|
146
|
+
ManifestBuilder::ResourceBuilder,
|
147
|
+
iiif_resource_factory: iiif_resource_factory,
|
148
|
+
image_service_builder_factory: image_service_builder_factory
|
149
|
+
)
|
150
|
+
end
|
151
|
+
|
152
|
+
def image_service_builder_factory
|
153
|
+
InjectedFactory.new(
|
154
|
+
ManifestBuilder::ImageServiceBuilder,
|
155
|
+
iiif_service_factory: iiif_service_factory
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
def iiif_service_factory
|
160
|
+
IIIF::Service
|
161
|
+
end
|
162
|
+
|
163
|
+
def iiif_resource_factory
|
164
|
+
IIIF::Presentation::Resource
|
165
|
+
end
|
166
|
+
|
167
|
+
def iiif_annotation_factory
|
168
|
+
IIIF::Presentation::Annotation
|
115
169
|
end
|
116
170
|
|
117
171
|
def iiif_manifest_factory
|
118
172
|
IIIF::Presentation::Manifest
|
119
173
|
end
|
174
|
+
|
175
|
+
def iiif_canvas_factory
|
176
|
+
IIIF::Presentation::Canvas
|
177
|
+
end
|
178
|
+
|
179
|
+
def iiif_range_factory
|
180
|
+
IIIF::Presentation::Range
|
181
|
+
end
|
120
182
|
end
|
121
183
|
|
122
184
|
class InjectedFactory
|
data/lib/iiif_manifest.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iiif_manifest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-10-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -81,6 +81,48 @@ dependencies:
|
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '3.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rubocop
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rubocop-rspec
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: pry-byebug
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
84
126
|
description: IIIF http://iiif.io/ defines an API for presenting related images in
|
85
127
|
a viewer. This transforms Hydra::Works objects into that format usable by players
|
86
128
|
such as http://universalviewer.io/
|
@@ -92,6 +134,8 @@ extra_rdoc_files: []
|
|
92
134
|
files:
|
93
135
|
- ".gitignore"
|
94
136
|
- ".rspec"
|
137
|
+
- ".rubocop.yml"
|
138
|
+
- ".rubocop_todo.yml"
|
95
139
|
- ".travis.yml"
|
96
140
|
- CODE_OF_CONDUCT.md
|
97
141
|
- Gemfile
|
@@ -117,6 +161,7 @@ files:
|
|
117
161
|
- lib/iiif_manifest/manifest_builder/record_property_builder.rb
|
118
162
|
- lib/iiif_manifest/manifest_builder/resource_builder.rb
|
119
163
|
- lib/iiif_manifest/manifest_builder/sequence_builder.rb
|
164
|
+
- lib/iiif_manifest/manifest_builder/structure_builder.rb
|
120
165
|
- lib/iiif_manifest/manifest_factory.rb
|
121
166
|
- lib/iiif_manifest/manifest_service_locator.rb
|
122
167
|
- lib/iiif_manifest/version.rb
|
@@ -139,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
184
|
version: '0'
|
140
185
|
requirements: []
|
141
186
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.6.
|
187
|
+
rubygems_version: 2.6.13
|
143
188
|
signing_key:
|
144
189
|
specification_version: 4
|
145
190
|
summary: Generate IIIF presentation manifests for Hydra::Works
|