iiif_manifest 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -0
  3. data/.rspec +0 -0
  4. data/.rubocop.yml +15 -0
  5. data/.rubocop_todo.yml +84 -0
  6. data/.travis.yml +0 -0
  7. data/CODE_OF_CONDUCT.md +0 -0
  8. data/Gemfile +0 -0
  9. data/LICENSE +0 -0
  10. data/README.md +48 -2
  11. data/Rakefile +12 -3
  12. data/bin/console +3 -3
  13. data/iiif_manifest.gemspec +17 -15
  14. data/lib/iiif_manifest/display_image.rb +0 -0
  15. data/lib/iiif_manifest/iiif_collection.rb +1 -0
  16. data/lib/iiif_manifest/iiif_endpoint.rb +1 -1
  17. data/lib/iiif_manifest/manifest_builder/canvas_builder.rb +15 -13
  18. data/lib/iiif_manifest/manifest_builder/canvas_builder_factory.rb +3 -3
  19. data/lib/iiif_manifest/manifest_builder/child_manifest_builder_factory.rb +0 -0
  20. data/lib/iiif_manifest/manifest_builder/composite_builder.rb +0 -0
  21. data/lib/iiif_manifest/manifest_builder/composite_builder_factory.rb +0 -0
  22. data/lib/iiif_manifest/manifest_builder/deep_canvas_builder_factory.rb +6 -6
  23. data/lib/iiif_manifest/manifest_builder/image_builder.rb +14 -12
  24. data/lib/iiif_manifest/manifest_builder/image_service_builder.rb +6 -5
  25. data/lib/iiif_manifest/manifest_builder/record_property_builder.rb +28 -11
  26. data/lib/iiif_manifest/manifest_builder/resource_builder.rb +13 -11
  27. data/lib/iiif_manifest/manifest_builder/sequence_builder.rb +23 -13
  28. data/lib/iiif_manifest/manifest_builder/structure_builder.rb +94 -0
  29. data/lib/iiif_manifest/manifest_builder.rb +9 -8
  30. data/lib/iiif_manifest/manifest_factory.rb +0 -0
  31. data/lib/iiif_manifest/manifest_service_locator.rb +65 -3
  32. data/lib/iiif_manifest/version.rb +1 -1
  33. data/lib/iiif_manifest.rb +1 -1
  34. metadata +48 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5708ab4381068e5d90cbc1607d2e8dafceb391e
4
- data.tar.gz: 6e064f9d5faa44116fdf986b09c05bf796f5267f
3
+ metadata.gz: 9bf49dd68d7cea2339444aafd8eb4f98ac3cdcd9
4
+ data.tar.gz: ddee2270d2cf0f5098c40ecee97fd696a59a36f1
5
5
  SHA512:
6
- metadata.gz: b736502a559e0a94918587c3ca9d94e3584050ad619431795b19be30e038b79a62e2272d14abcfe144f7324f33ec841018dccffd80faa1546e6642b9dac97774
7
- data.tar.gz: 4e6415c54ee2c842f98492259f1be5326947414d312b949f30c71b67a9893c2847c8dfd0003c0af310f3206543d457ace81a35f484245b211aacebdbdc6c06b9
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
@@ -0,0 +1,15 @@
1
+ require: rubocop-rspec
2
+ inherit_from: .rubocop_todo.yml
3
+
4
+ AllCops:
5
+ DisplayCopNames: true
6
+
7
+ Metrics/LineLength:
8
+ Max: 120
9
+
10
+ Metrics/BlockLength:
11
+ Exclude:
12
+ - 'spec/**/*.rb'
13
+
14
+ RSpec/MultipleExpectations:
15
+ Enabled: false
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
- You 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. Additionally it should implement `#manifest_url` that shows where the manifest can be found. Finally, it must have a `#description` method that returns a string.
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 "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
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
- task :default => :spec
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 "bundler/setup"
4
- require "iiif_manifest"
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 "irb"
13
+ require 'irb'
14
14
  IRB.start
@@ -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 = "iiif_manifest"
6
+ spec.name = 'iiif_manifest'
8
7
  spec.version = IIIFManifest::VERSION
9
- spec.authors = ["Justin Coyne", "Trey Pendragon"]
10
- spec.email = ["jcoyne@justincoyne.com"]
8
+ spec.authors = ['Justin Coyne', 'Trey Pendragon']
9
+ spec.email = ['jcoyne@justincoyne.com']
11
10
 
12
- spec.summary = %q{Generate IIIF presentation manifests for Hydra::Works}
13
- spec.description = %q{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/}
14
- spec.homepage = "http://github.com/projecthydra-labs/iiif_manifest"
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 = "exe"
16
+ spec.bindir = 'exe'
18
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
20
19
 
21
- spec.add_dependency "activesupport", ">= 4"
22
- spec.add_dependency "iiif-presentation", '~> 0.2.0'
23
-
24
- spec.add_development_dependency "bundler", "~> 1.11"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
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,5 +1,6 @@
1
1
  class IIIFCollection < SimpleDelegator
2
2
  def viewing_hint
3
+ return super if __getobj__.respond_to?(:viewing_hint)
3
4
  'multi-part'
4
5
  end
5
6
  end
@@ -7,7 +7,7 @@ module IIIFManifest
7
7
  end
8
8
 
9
9
  def context
10
- "http://iiif.io/api/image/2/context.json"
10
+ 'http://iiif.io/api/image/2/context.json'
11
11
  end
12
12
  end
13
13
  end
@@ -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 ||= IIIF::Presentation::Canvas.new
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
- def display_image
30
- record.display_image if record.respond_to?(:display_image)
31
- end
31
+ def display_image
32
+ record.display_image if record.respond_to?(:display_image)
33
+ end
32
34
 
33
- def apply_record_properties
34
- canvas['@id'] = path
35
- canvas.label = record.to_s
36
- end
35
+ def apply_record_properties
36
+ canvas['@id'] = path
37
+ canvas.label = record.to_s
38
+ end
37
39
 
38
- def attach_image
39
- ImageBuilder.new(display_image).apply(canvas)
40
- end
40
+ def attach_image
41
+ image_builder.new(display_image).apply(canvas)
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -17,9 +17,9 @@ module IIIFManifest
17
17
 
18
18
  private
19
19
 
20
- def file_set_presenters(work)
21
- work.file_set_presenters
22
- end
20
+ def file_set_presenters(work)
21
+ work.file_set_presenters
22
+ end
23
23
  end
24
24
  end
25
25
  end
@@ -26,13 +26,13 @@ module IIIFManifest
26
26
 
27
27
  private
28
28
 
29
- def file_set_presenters
30
- work.try(:file_set_presenters) || []
31
- end
29
+ def file_set_presenters
30
+ work.try(:file_set_presenters) || []
31
+ end
32
32
 
33
- def work_presenters
34
- work.try(:work_presenters) || []
35
- end
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 << annotation
16
+ canvas.images += [annotation]
15
17
  end
16
18
 
17
19
  private
18
20
 
19
- def build_resource
20
- resource_builder.apply(annotation)
21
- end
21
+ def build_resource
22
+ resource_builder.apply(annotation)
23
+ end
22
24
 
23
- def resource_builder
24
- ResourceBuilder.new(display_image)
25
- end
25
+ def resource_builder
26
+ resource_builder_factory.new(display_image)
27
+ end
26
28
 
27
- def annotation
28
- @annotation ||= IIIF::Presentation::Annotation.new
29
- end
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
- def service
19
- @service ||= IIIF::Service.new
20
- end
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
- def viewing_hint
21
- (record.respond_to?(:viewing_hint) && record.send(:viewing_hint)) || 'individuals'
22
- end
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
- # def viewing_direction
25
- # record.try(:viewing_direction) || "left-to-right"
26
- # end
33
+ # Manifest metadata must be an array containing hashes
27
34
  #
28
- # def viewing_hint
29
- # record.viewing_hint || "individuals"
30
- # end
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
- def resource
22
- @resource ||= IIIF::Presentation::Resource.new
23
- end
23
+ def resource
24
+ @resource ||= iiif_resource_factory.new
25
+ end
24
26
 
25
- def iiif_endpoint
26
- display_image.try(:iiif_endpoint)
27
- end
27
+ def iiif_endpoint
28
+ display_image.try(:iiif_endpoint)
29
+ end
28
30
 
29
- def image_service_builder
30
- ImageServiceBuilder.new(iiif_endpoint)
31
- end
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
- def canvas_builder
23
- canvas_builder_factory.from(work)
24
- end
23
+ def canvas_builder
24
+ canvas_builder_factory.from(work)
25
+ end
25
26
 
26
- def sequence
27
- @sequence ||=
28
- begin
29
- sequence = IIIF::Presentation::Sequence.new
30
- sequence["@id"] ||= work.manifest_url + "/sequence/normal"
31
- canvas_builder.apply(sequence)
32
- sequence
33
- end
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["manifests"] ||= []
26
- collection["manifests"] << to_h
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
- def manifest
37
- @manifest ||= manifest_builder_class
38
- end
37
+ def manifest
38
+ @manifest ||= manifest_builder_class
39
+ end
39
40
 
40
- def top_record
41
- top_record_factory.new
42
- end
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
- ManifestBuilder::CanvasBuilder
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
@@ -1,3 +1,3 @@
1
1
  module IIIFManifest
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/iiif_manifest.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "iiif_manifest/version"
1
+ require 'iiif_manifest/version'
2
2
  require 'active_support'
3
3
  require 'active_support/core_ext/module'
4
4
  require 'active_support/core_ext/object'
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.2.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-05-03 00:00:00.000000000 Z
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.12
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