iiif-presentation 1.4.1 → 1.5.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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +8 -1
  3. data/.standard.yml +1 -0
  4. data/Gemfile +5 -5
  5. data/README.md +1 -1
  6. data/Rakefile +4 -2
  7. data/VERSION +1 -1
  8. data/bin/standardrb +16 -0
  9. data/iiif-presentation.gemspec +23 -23
  10. data/lib/iiif/hash_behaviours.rb +29 -33
  11. data/lib/iiif/ordered_hash.rb +33 -33
  12. data/lib/iiif/presentation/abstract_resource.rb +17 -22
  13. data/lib/iiif/presentation/annotation.rb +9 -11
  14. data/lib/iiif/presentation/annotation_list.rb +8 -10
  15. data/lib/iiif/presentation/canvas.rb +11 -13
  16. data/lib/iiif/presentation/collection.rb +7 -9
  17. data/lib/iiif/presentation/image_resource.rb +33 -35
  18. data/lib/iiif/presentation/layer.rb +8 -10
  19. data/lib/iiif/presentation/manifest.rb +9 -12
  20. data/lib/iiif/presentation/range.rb +8 -10
  21. data/lib/iiif/presentation/resource.rb +5 -7
  22. data/lib/iiif/presentation/sequence.rb +8 -11
  23. data/lib/iiif/presentation/service.rb +1 -2
  24. data/lib/iiif/presentation.rb +7 -7
  25. data/lib/iiif/service.rb +121 -102
  26. data/lib/iiif/v3/abstract_resource.rb +132 -144
  27. data/lib/iiif/v3/presentation/annotation.rb +20 -21
  28. data/lib/iiif/v3/presentation/annotation_collection.rb +7 -9
  29. data/lib/iiif/v3/presentation/annotation_page.rb +14 -15
  30. data/lib/iiif/v3/presentation/canvas.rb +21 -22
  31. data/lib/iiif/v3/presentation/choice.rb +14 -15
  32. data/lib/iiif/v3/presentation/collection.rb +7 -8
  33. data/lib/iiif/v3/presentation/image_resource.rb +21 -22
  34. data/lib/iiif/v3/presentation/manifest.rb +18 -19
  35. data/lib/iiif/v3/presentation/nav_place.rb +125 -29
  36. data/lib/iiif/v3/presentation/range.rb +10 -10
  37. data/lib/iiif/v3/presentation/resource.rb +4 -5
  38. data/lib/iiif/v3/presentation/sequence.rb +10 -11
  39. data/lib/iiif/v3/presentation/service.rb +12 -13
  40. data/lib/iiif/v3/presentation.rb +8 -8
  41. data/spec/integration/iiif/presentation/image_resource_spec.rb +54 -58
  42. data/spec/integration/iiif/service_spec.rb +76 -77
  43. data/spec/integration/iiif/v3/abstract_resource_spec.rb +73 -73
  44. data/spec/integration/iiif/v3/presentation/image_resource_spec.rb +53 -56
  45. data/spec/spec_helper.rb +56 -64
  46. data/spec/unit/iiif/hash_behaviours_spec.rb +384 -387
  47. data/spec/unit/iiif/ordered_hash_spec.rb +86 -91
  48. data/spec/unit/iiif/presentation/abstract_resource_spec.rb +64 -70
  49. data/spec/unit/iiif/presentation/annotation_list_spec.rb +1 -3
  50. data/spec/unit/iiif/presentation/annotation_spec.rb +1 -3
  51. data/spec/unit/iiif/presentation/canvas_spec.rb +11 -14
  52. data/spec/unit/iiif/presentation/collection_spec.rb +26 -33
  53. data/spec/unit/iiif/presentation/image_resource_spec.rb +4 -6
  54. data/spec/unit/iiif/presentation/layer_spec.rb +16 -20
  55. data/spec/unit/iiif/presentation/manifest_spec.rb +45 -48
  56. data/spec/unit/iiif/presentation/range_spec.rb +18 -22
  57. data/spec/unit/iiif/presentation/resource_spec.rb +3 -6
  58. data/spec/unit/iiif/presentation/sequence_spec.rb +58 -63
  59. data/spec/unit/iiif/presentation/shared_examples/abstract_resource_only_keys.rb +4 -10
  60. data/spec/unit/iiif/presentation/shared_examples/any_type_keys.rb +5 -9
  61. data/spec/unit/iiif/presentation/shared_examples/array_only_keys.rb +9 -17
  62. data/spec/unit/iiif/presentation/shared_examples/int_only_keys.rb +6 -14
  63. data/spec/unit/iiif/presentation/shared_examples/string_only_keys.rb +6 -13
  64. data/spec/unit/iiif/service_spec.rb +8 -13
  65. data/spec/unit/iiif/v3/abstract_resource_define_methods_for_spec.rb +39 -37
  66. data/spec/unit/iiif/v3/abstract_resource_spec.rb +128 -143
  67. data/spec/unit/iiif/v3/presentation/annotation_collection_spec.rb +14 -17
  68. data/spec/unit/iiif/v3/presentation/annotation_page_spec.rb +71 -69
  69. data/spec/unit/iiif/v3/presentation/annotation_spec.rb +249 -233
  70. data/spec/unit/iiif/v3/presentation/canvas_spec.rb +211 -193
  71. data/spec/unit/iiif/v3/presentation/choice_spec.rb +81 -77
  72. data/spec/unit/iiif/v3/presentation/collection_spec.rb +24 -29
  73. data/spec/unit/iiif/v3/presentation/image_resource_spec.rb +70 -71
  74. data/spec/unit/iiif/v3/presentation/manifest_spec.rb +248 -237
  75. data/spec/unit/iiif/v3/presentation/nav_place_spec.rb +249 -49
  76. data/spec/unit/iiif/v3/presentation/range_spec.rb +28 -29
  77. data/spec/unit/iiif/v3/presentation/resource_spec.rb +83 -82
  78. data/spec/unit/iiif/v3/presentation/sequence_spec.rb +126 -120
  79. data/spec/unit/iiif/v3/presentation/service_spec.rb +123 -124
  80. data/spec/unit/iiif/v3/presentation/shared_examples/abstract_resource_only_keys.rb +4 -8
  81. data/spec/unit/iiif/v3/presentation/shared_examples/any_type_keys.rb +5 -7
  82. data/spec/unit/iiif/v3/presentation/shared_examples/array_only_keys.rb +9 -13
  83. data/spec/unit/iiif/v3/presentation/shared_examples/hash_only_keys.rb +9 -13
  84. data/spec/unit/iiif/v3/presentation/shared_examples/int_only_keys.rb +6 -10
  85. data/spec/unit/iiif/v3/presentation/shared_examples/numeric_only_keys.rb +6 -10
  86. data/spec/unit/iiif/v3/presentation/shared_examples/string_only_keys.rb +6 -10
  87. data/spec/unit/iiif/v3/presentation/shared_examples/uri_only_keys.rb +9 -13
  88. metadata +27 -69
@@ -1,41 +1,40 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Canvas < AbstractResource
6
-
7
6
  # TODO (?) a simple 'Image Canvas' constructor.
8
7
 
9
- TYPE = 'sc:Canvas'
8
+ TYPE = "sc:Canvas"
10
9
 
11
10
  def required_keys
12
- super + %w{ @id width height label }
11
+ super + %w[@id width height label]
13
12
  end
14
13
 
15
14
  def any_type_keys
16
- super + %w{ }
15
+ super + %w[]
17
16
  end
18
17
 
19
18
  def array_only_keys
20
- super + %w{ images other_content }
19
+ super + %w[images other_content]
21
20
  end
22
21
 
23
22
  # TODO: test and validate
24
23
  def int_only_keys
25
- super + %w{ width height }
24
+ super + %w[width height]
26
25
  end
27
26
 
28
27
  def numeric_only_keys
29
- super + %w{ duration }
28
+ super + %w[duration]
30
29
  end
31
30
 
32
31
  def legal_viewing_hint_values
33
- super + %w{ non-paged }
32
+ super + %w[non-paged]
34
33
  end
35
34
 
36
- def initialize(hsh={})
37
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
38
- super(hsh)
35
+ def initialize(hsh = {})
36
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
37
+ super
39
38
  end
40
39
 
41
40
  def validate
@@ -43,7 +42,6 @@ module IIIF
43
42
  # all members of otherContent must be an annotation list
44
43
  super
45
44
  end
46
-
47
45
  end
48
46
  end
49
47
  end
@@ -1,29 +1,27 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Collection < AbstractResource
6
-
7
- TYPE = 'sc:Collection'
6
+ TYPE = "sc:Collection"
8
7
 
9
8
  def required_keys
10
- super + %w{ @id label }
9
+ super + %w[@id label]
11
10
  end
12
11
 
13
12
  def array_only_keys
14
- super + %w{ collections manifests }
13
+ super + %w[collections manifests]
15
14
  end
16
15
 
17
- def initialize(hsh={})
18
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
19
- super(hsh)
16
+ def initialize(hsh = {})
17
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
18
+ super
20
19
  end
21
20
 
22
21
  def validate
23
22
  # each member of collections and manifests must be a Hash
24
23
  # each member of collections and manifests MUST have @id, @type, and label
25
24
  end
26
-
27
25
  end
28
26
  end
29
27
  end
@@ -1,44 +1,43 @@
1
- require File.join(File.dirname(__FILE__), 'resource')
2
- require 'faraday'
3
- require 'json'
1
+ require File.join(File.dirname(__FILE__), "resource")
2
+ require "faraday"
3
+ require "json"
4
4
 
5
5
  module IIIF
6
6
  module Presentation
7
7
  class ImageResource < Resource
8
-
9
- TYPE = 'dctypes:Image'
8
+ TYPE = "dctypes:Image"
10
9
 
11
10
  def int_only_keys
12
- super + %w{ width height }
11
+ super + %w[width height]
13
12
  end
14
13
 
15
- def initialize(hsh={})
16
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
17
- super(hsh)
14
+ def initialize(hsh = {})
15
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
16
+ super
18
17
  end
19
18
 
20
19
  class << self
21
- IMAGE_API_DEFAULT_PARAMS = '/full/!200,200/0/default.jpg'
22
- IMAGE_API_CONTEXT = 'http://iiif.io/api/image/2/context.json'
23
- DEFAULT_FORMAT = 'image/jpeg'
20
+ IMAGE_API_DEFAULT_PARAMS = "/full/!200,200/0/default.jpg"
21
+ IMAGE_API_CONTEXT = "http://iiif.io/api/image/2/context.json"
22
+ DEFAULT_FORMAT = "image/jpeg"
24
23
  # Create a new ImageResource that includes a IIIF Image API Service
25
24
  # See http://iiif.io/api/presentation/2.0/#image-resources
26
25
  #
27
26
  # Params
28
- # * :service_id (required) - The base URI for the image on the image
27
+ # * :service_id (required) - The base URI for the image on the image
29
28
  # server.
30
- # * :resource_id - The id for the resource; if supplied this should
31
- # resolve to an actual image. Default:
29
+ # * :resource_id - The id for the resource; if supplied this should
30
+ # resolve to an actual image. Default:
32
31
  # "#{:service_id}/full/!200,200/0/default.jpg"
33
- # * :format - The format of the image that is returned when
32
+ # * :format - The format of the image that is returned when
34
33
  # `:resource_id` is resolved. Default: 'image/jpeg'
35
34
  # * :height (Integer)
36
35
  # * :profile (String)
37
- # * :width (Integer) - If width, height, and profile are not supplied,
38
- # this method will try to get the info from the server (based on
36
+ # * :width (Integer) - If width, height, and profile are not supplied,
37
+ # this method will try to get the info from the server (based on
39
38
  # :resource_id) and raise an Exception if this is not possible for
40
39
  # some reason.
41
- # * :copy_info (bool)- Even if width and height are supplied, try to
40
+ # * :copy_info (bool)- Even if width and height are supplied, try to
42
41
  # get the info.json from the server and copy it in. Default: false
43
42
  #
44
43
  # Raises:
@@ -60,8 +59,7 @@ module IIIF
60
59
  # "width":1500
61
60
  # }
62
61
  #
63
- def create_image_api_image_resource(params={})
64
-
62
+ def create_image_api_image_resource(params = {})
65
63
  service_id = params.fetch(:service_id)
66
64
  resource_id_default = "#{service_id}#{IMAGE_API_DEFAULT_PARAMS}"
67
65
  resource_id = params.fetch(:resource_id, resource_id_default)
@@ -70,36 +68,37 @@ module IIIF
70
68
  profile = params.fetch(:profile, nil)
71
69
  width = params.fetch(:width, nil)
72
70
  copy_info = params.fetch(:copy_info, false)
73
-
71
+
74
72
  have_whp = [width, height, profile].all? { |prop| !prop.nil? }
75
73
 
76
74
  remote_info = get_info(service_id) if !have_whp || copy_info
77
75
 
78
- resource = self.new
79
- resource['@id'] = resource_id
76
+ resource = new
77
+ resource["@id"] = resource_id
80
78
  resource.format = format
81
- resource.width = width.nil? ? remote_info['width'] : width
82
- resource.height = height.nil? ? remote_info['height'] : height
79
+ resource.width = width.nil? ? remote_info["width"] : width
80
+ resource.height = height.nil? ? remote_info["height"] : height
83
81
  resource.service = Service.new
84
82
  if copy_info
85
83
  resource.service.merge!(remote_info)
86
84
  else
87
- resource.service['@context'] = IMAGE_API_CONTEXT
88
- resource.service['@id'] = service_id
89
- if profile.nil?
90
- if remote_info['profile'].kind_of?(Array)
91
- resource.service['profile'] = remote_info['profile'][0]
85
+ resource.service["@context"] = IMAGE_API_CONTEXT
86
+ resource.service["@id"] = service_id
87
+ resource.service["profile"] = if profile.nil?
88
+ if remote_info["profile"].is_a?(Array)
89
+ remote_info["profile"][0]
92
90
  else
93
- resource.service['profile'] = remote_info['profile']
91
+ remote_info["profile"]
94
92
  end
95
93
  else
96
- resource.service['profile'] = profile
94
+ profile
97
95
  end
98
96
  end
99
- return resource
97
+ resource
100
98
  end
101
99
 
102
100
  protected
101
+
103
102
  def get_info(svc_id)
104
103
  conn = Faraday.new("#{svc_id}/info.json") do |c|
105
104
  c.use Faraday::Response::RaiseError
@@ -114,7 +113,6 @@ module IIIF
114
113
  JSON.parse(resp.body)
115
114
  end
116
115
  end
117
-
118
116
  end
119
117
  end
120
118
  end
@@ -1,26 +1,25 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Layer < AbstractResource
6
-
7
- TYPE = 'sc:Layer'
6
+ TYPE = "sc:Layer"
8
7
 
9
8
  def required_keys
10
- super + %w{ @id label }
9
+ super + %w[@id label]
11
10
  end
12
11
 
13
12
  def array_only_keys
14
- super + %w{ other_content }
13
+ super + %w[other_content]
15
14
  end
16
15
 
17
16
  def string_only_keys
18
- super + %w{ viewing_direction } # should any of the any_type_keys be here?
17
+ super + %w[viewing_direction] # should any of the any_type_keys be here?
19
18
  end
20
19
 
21
- def initialize(hsh={})
22
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
23
- super(hsh)
20
+ def initialize(hsh = {})
21
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
22
+ super
24
23
  end
25
24
 
26
25
  def validate
@@ -28,7 +27,6 @@ module IIIF
28
27
  # can they be inline?
29
28
  super
30
29
  end
31
-
32
30
  end
33
31
  end
34
32
  end
@@ -1,30 +1,29 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Manifest < AbstractResource
6
-
7
- TYPE = 'sc:Manifest'
6
+ TYPE = "sc:Manifest"
8
7
 
9
8
  def required_keys
10
- super + %w{ @id label }
9
+ super + %w[@id label]
11
10
  end
12
11
 
13
12
  def string_only_keys
14
- super + %w{ viewing_direction }
13
+ super + %w[viewing_direction]
15
14
  end
16
15
 
17
16
  def array_only_keys
18
- super + %w{ sequences structures }
17
+ super + %w[sequences structures]
19
18
  end
20
19
 
21
20
  def legal_viewing_hint_values
22
- %w{ individuals paged continuous }
21
+ %w[individuals paged continuous]
23
22
  end
24
23
 
25
- def initialize(hsh={})
26
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
27
- super(hsh)
24
+ def initialize(hsh = {})
25
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
26
+ super
28
27
  end
29
28
 
30
29
  def validate
@@ -32,8 +31,6 @@ module IIIF
32
31
 
33
32
  super
34
33
  end
35
-
36
34
  end
37
35
  end
38
36
  end
39
-
@@ -1,32 +1,30 @@
1
- require File.join(File.dirname(__FILE__), 'sequence')
1
+ require File.join(File.dirname(__FILE__), "sequence")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Range < Sequence
6
-
7
- TYPE = 'sc:Range'
6
+ TYPE = "sc:Range"
8
7
 
9
8
  def required_keys
10
- super + %w{ @id label }
9
+ super + %w[@id label]
11
10
  end
12
11
 
13
12
  def array_only_keys
14
- super + %w{ ranges }
13
+ super + %w[ranges]
15
14
  end
16
15
 
17
16
  def legal_viewing_hint_values
18
- super + %w{ top }
17
+ super + %w[top]
19
18
  end
20
19
 
21
- def initialize(hsh={})
22
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
23
- super(hsh)
20
+ def initialize(hsh = {})
21
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
22
+ super
24
23
  end
25
24
 
26
25
  def validate
27
26
  # Values of the ranges array must be strings
28
27
  end
29
-
30
28
  end
31
29
  end
32
30
  end
@@ -1,21 +1,19 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Resource < AbstractResource
6
-
7
6
  def required_keys
8
- %w{ @id }
7
+ %w[@id]
9
8
  end
10
9
 
11
10
  def string_only_keys
12
- super + %w{ format }
11
+ super + %w[format]
13
12
  end
14
13
 
15
- def initialize(hsh={})
16
- super(hsh)
14
+ def initialize(hsh = {})
15
+ super
17
16
  end
18
-
19
17
  end
20
18
  end
21
19
  end
@@ -1,26 +1,25 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
5
5
  class Sequence < AbstractResource
6
-
7
- TYPE = 'sc:Sequence'
6
+ TYPE = "sc:Sequence"
8
7
 
9
8
  def array_only_keys
10
- super + %w{ canvases }
9
+ super + %w[canvases]
11
10
  end
12
11
 
13
12
  def string_only_keys
14
- super + %w{ start_canvas viewing_direction }
13
+ super + %w[start_canvas viewing_direction]
15
14
  end
16
15
 
17
16
  def legal_viewing_hint_values
18
- %w{ individuals paged continuous }
17
+ %w[individuals paged continuous]
19
18
  end
20
19
 
21
- def initialize(hsh={})
22
- hsh['@type'] = TYPE unless hsh.has_key? '@type'
23
- super(hsh)
20
+ def initialize(hsh = {})
21
+ hsh["@type"] = TYPE unless hsh.has_key? "@type"
22
+ super
24
23
  end
25
24
 
26
25
  def validate
@@ -28,8 +27,6 @@ module IIIF
28
27
  # * All members of canvases must be a kind of Canvas
29
28
  super
30
29
  end
31
-
32
30
  end
33
31
  end
34
32
  end
35
-
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_resource')
1
+ require File.join(File.dirname(__FILE__), "abstract_resource")
2
2
 
3
3
  module IIIF
4
4
  module Presentation
@@ -9,4 +9,3 @@ module IIIF
9
9
  end
10
10
  end
11
11
  end
12
-
@@ -1,5 +1,5 @@
1
- require File.join(File.dirname(__FILE__), 'service')
2
- %w{
1
+ require File.join(File.dirname(__FILE__), "service")
2
+ %w[
3
3
  abstract_resource
4
4
  annotation
5
5
  annotation_list
@@ -8,19 +8,19 @@ require File.join(File.dirname(__FILE__), 'service')
8
8
  layer
9
9
  manifest
10
10
  resource
11
- image_resource
11
+ image_resource
12
12
  sequence
13
13
  service
14
14
  range
15
- }.each do |f|
16
- require File.join(File.dirname(__FILE__), 'presentation', f)
15
+ ].each do |f|
16
+ require File.join(File.dirname(__FILE__), "presentation", f)
17
17
  end
18
18
 
19
- require_relative 'ordered_hash'
19
+ require_relative "ordered_hash"
20
20
 
21
21
  module IIIF
22
22
  module Presentation
23
- CONTEXT ||= 'http://iiif.io/api/presentation/2/context.json'
23
+ CONTEXT = "http://iiif.io/api/presentation/2/context.json"
24
24
 
25
25
  class MissingRequiredKeyError < StandardError; end
26
26
  class IllegalValueError < StandardError; end