iiif-presentation 1.4.0 → 1.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d5fac69b52d8f3510fa40fc221882302736f9b4afe8b55b1330497ab11d8033
4
- data.tar.gz: 9156c96e93409320cddde7d86bb78894b6351cd2c291ab6bdca39958d3f27bbc
3
+ metadata.gz: 5f68d7e5cd133fa903625a262109591f8806016df292b205b9cda95f8cb4b5d0
4
+ data.tar.gz: 0fc72efe6625543c1c8462bbf0b810fe5882c5dbdee6156410654e9c29be6825
5
5
  SHA512:
6
- metadata.gz: 85f3b92e738793e5360cdff614c6f50fd271cb7b1033a6df1de8452603a18b4aa6cb0c6e4c9e5639f0587c6d1666cb47054c4b99894e398ee4a3c1fcfa08bd09
7
- data.tar.gz: be3fc1d37352d21c018cffc8c2315d221aadcd00fad0c46847ffe1d68b131b6bc3844abf08ba6bd5cf56c049df706a31e1300c3279fa98b3fb1e43d267a34187
6
+ metadata.gz: bd825465b2f3d72e6003b7db8e5ac8020040daf36a924d35b0d8553e4e51910ca880e5017cc9e2b86f6424ef1ca1febe6010f28b52eb657d6d66713a6b31344d
7
+ data.tar.gz: dbb55a55e296777bfc1e422132604b83c53cdc16d63ba404575f1d4baee0afda7fc8cdb8f95480b4bdf83df6c23a4947d447306491ca65eb37273b717dce7e73
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.4.1
@@ -347,7 +347,9 @@ module IIIF
347
347
  hsh.keys.each do |key|
348
348
  new_key = key.underscore == key ? key : key.underscore
349
349
  if new_key == 'service'
350
- new_object[new_key] = IIIF::V3::AbstractResource.from_ordered_hash(hsh[key], IIIF::V3::Presentation::Service)
350
+ new_object[new_key] = hsh[key].map do |entry|
351
+ IIIF::V3::AbstractResource.from_ordered_hash(entry, IIIF::V3::Presentation::Service)
352
+ end
351
353
  elsif new_key == 'body'
352
354
  new_object[new_key] = IIIF::V3::AbstractResource.from_ordered_hash(hsh[key], IIIF::V3::Presentation::Resource)
353
355
  elsif hsh[key].kind_of?(Hash)
@@ -63,8 +63,6 @@ module IIIF
63
63
  end
64
64
  end
65
65
 
66
- # NOTE: allowing 'items' or 'sequences' as Universal Viewer currently only accepts sequences
67
- # see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
68
66
  def validate_items_list(items_array)
69
67
  unless items_array.size >= 1
70
68
  m = 'The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)'
@@ -28,11 +28,13 @@
28
28
  "description": "A longer description of this example book. It should give some real information.",
29
29
  "rights": "http://www.example.org/license.html",
30
30
  "attribution": "Provided by Example Organization",
31
- "service": {
32
- "@context": "http://example.org/ns/jsonld/context.json",
33
- "id": "http://example.org/service/example",
34
- "profile": "http://example.org/docs/example-service.html"
35
- },
31
+ "service": [
32
+ {
33
+ "@context": "http://example.org/ns/jsonld/context.json",
34
+ "id": "http://example.org/service/example",
35
+ "profile": "http://example.org/docs/example-service.html"
36
+ }
37
+ ],
36
38
  "seeAlso": {
37
39
  "id": "http://www.example.org/library/catalog/book1.marc",
38
40
  "format": "application/marc"
@@ -67,11 +69,13 @@
67
69
  "format": "image/jpeg",
68
70
  "height": 2000,
69
71
  "width": 1500,
70
- "service": {
71
- "@context": "http://iiif.io/api/image/2/context.json",
72
- "id": "http://www.example.org/images/book1-page1",
73
- "profile": "http://iiif.io/api/image/2/level1.json"
74
- }
72
+ "service": [
73
+ {
74
+ "@context": "http://iiif.io/api/image/2/context.json",
75
+ "id": "http://www.example.org/images/book1-page1",
76
+ "profile": "http://iiif.io/api/image/2/level1.json"
77
+ }
78
+ ]
75
79
  }
76
80
  }
77
81
  ]
@@ -102,25 +106,27 @@
102
106
  "format": "image/jpeg",
103
107
  "height": 2000,
104
108
  "width": 1500,
105
- "service": {
106
- "@context": "http://iiif.io/api/image/2/context.json",
107
- "id": "http://www.example.org/images/book1-page2",
108
- "profile": "http://iiif.io/api/image/2/level1.json",
109
- "height": 8000,
110
- "width": 6000,
111
- "tiles": [
112
- {
113
- "width": 512,
114
- "scaleFactors": [
115
- 1,
116
- 2,
117
- 4,
118
- 8,
119
- 16
120
- ]
121
- }
122
- ]
123
- }
109
+ "service": [
110
+ {
111
+ "@context": "http://iiif.io/api/image/2/context.json",
112
+ "id": "http://www.example.org/images/book1-page2",
113
+ "profile": "http://iiif.io/api/image/2/level1.json",
114
+ "height": 8000,
115
+ "width": 6000,
116
+ "tiles": [
117
+ {
118
+ "width": 512,
119
+ "scaleFactors": [
120
+ 1,
121
+ 2,
122
+ 4,
123
+ 8,
124
+ 16
125
+ ]
126
+ }
127
+ ]
128
+ }
129
+ ]
124
130
  },
125
131
  "target": "http://www.example.org/iiif/book1/canvas/p2"
126
132
  }
@@ -153,11 +159,13 @@
153
159
  "format": "image/jpeg",
154
160
  "height": 2000,
155
161
  "width": 1500,
156
- "service": {
157
- "@context": "http://iiif.io/api/image/2/context.json",
158
- "id": "http://www.example.org/images/book1-page3",
159
- "profile": "http://iiif.io/api/image/2/level1.json"
160
- }
162
+ "service": [
163
+ {
164
+ "@context": "http://iiif.io/api/image/2/context.json",
165
+ "id": "http://www.example.org/images/book1-page3",
166
+ "profile": "http://iiif.io/api/image/2/level1.json"
167
+ }
168
+ ]
161
169
  }
162
170
  }
163
171
  ]
@@ -32,11 +32,13 @@
32
32
  "format": "image/jpeg",
33
33
  "height": 2000,
34
34
  "width": 1500,
35
- "service": {
36
- "@context": "http://iiif.io/api/image/2/context.json",
37
- "id": "http://www.example.org/images/book1-page1",
38
- "profile": "http://iiif.io/api/image/2/level1.json"
39
- }
35
+ "service": [
36
+ {
37
+ "@context": "http://iiif.io/api/image/2/context.json",
38
+ "id": "http://www.example.org/images/book1-page1",
39
+ "profile": "http://iiif.io/api/image/2/level1.json"
40
+ }
41
+ ]
40
42
  }
41
43
  }
42
44
  ]
@@ -6,9 +6,11 @@
6
6
  "type": "Manifest",
7
7
  "id": "http://www.example.org/iiif/book1/manifest",
8
8
  "label": "Book 1",
9
- "service": {
10
- "@context": "http://example.org/ns/jsonld/context.json",
11
- "id": "http://example.org/service/example",
12
- "profile": "http://example.org/docs/example-service.html"
13
- }
9
+ "service": [
10
+ {
11
+ "@context": "http://example.org/ns/jsonld/context.json",
12
+ "id": "http://example.org/service/example",
13
+ "profile": "http://example.org/docs/example-service.html"
14
+ }
15
+ ]
14
16
  }
@@ -47,12 +47,14 @@ describe IIIF::V3::AbstractResource do
47
47
  "id": "http://example.com/manifest",
48
48
  "type": "Manifest",
49
49
  "label": "My Manifest",
50
- "service": {
51
- "@context": "http://iiif.io/api/image/2/context.json",
52
- "@id":"http://www.example.org/images/book1-page1",
53
- "id":"http://www.example.org/images/book1-page1",
54
- "profile":"http://iiif.io/api/image/2/profiles/level2.json"
55
- },
50
+ "service": [
51
+ {
52
+ "@context": "http://iiif.io/api/image/2/context.json",
53
+ "@id":"http://www.example.org/images/book1-page1",
54
+ "id":"http://www.example.org/images/book1-page1",
55
+ "profile":"http://iiif.io/api/image/2/profiles/level2.json"
56
+ }
57
+ ],
56
58
  "some_other_thing": {
57
59
  "foo" : "bar"
58
60
  },
@@ -95,7 +97,7 @@ describe IIIF::V3::AbstractResource do
95
97
  it 'turns services into Services' do
96
98
  expected_klass = IIIF::V3::Presentation::Service
97
99
  parsed = described_class.from_ordered_hash(fixture)
98
- expect(parsed['service'].class).to be expected_klass
100
+ expect(parsed['service'].map(&:class).uniq).to contain_exactly expected_klass
99
101
  end
100
102
 
101
103
  it 'round-trips' do
@@ -12,7 +12,7 @@ describe IIIF::V3::Presentation::Annotation do
12
12
  'id' => content_id,
13
13
  'type' => content_type,
14
14
  'format' => mimetype,
15
- 'service' => image_2_api_service
15
+ 'service' => [image_2_api_service]
16
16
  )}
17
17
 
18
18
  describe '#required_keys' do
@@ -183,14 +183,16 @@ describe IIIF::V3::Presentation::Annotation do
183
183
  let(:img_mime) { 'image/jpeg' }
184
184
  let(:img_h) { 2000 }
185
185
  let(:img_w) { 1500 }
186
- let(:img_hw_resource) { IIIF::V3::Presentation::ImageResource.new(
187
- 'id' => content_id,
188
- 'type' => img_type,
189
- 'format' => img_mime,
190
- 'height' => img_h,
191
- 'width' => img_w,
192
- 'service' => image_2_api_service
193
- )}
186
+ let(:img_hw_resource) do
187
+ IIIF::V3::Presentation::ImageResource.new(
188
+ 'id' => content_id,
189
+ 'type' => img_type,
190
+ 'format' => img_mime,
191
+ 'height' => img_h,
192
+ 'width' => img_w,
193
+ 'service' => [image_2_api_service]
194
+ )
195
+ end
194
196
  let(:my_anno) {
195
197
  anno = described_class.new
196
198
  anno['id'] = anno_id
@@ -209,22 +211,23 @@ describe IIIF::V3::Presentation::Annotation do
209
211
 
210
212
  describe 'and service with height and width and tiles' do
211
213
  let(:tiles_val) { [{"width" => 512, "scaleFactors" => [1,2,4,8,16]}] }
212
- let(:service) {
214
+ let(:service) do
213
215
  s = image_2_api_service
214
216
  s['height'] = 8000
215
217
  s['width'] = 6000
216
218
  s['tiles'] = tiles_val
217
- s
218
- }
219
+ [s]
220
+ end
219
221
  it 'validates' do
220
222
  img_hw_resource['service'] = service
221
223
  expect{my_anno.validate}.not_to raise_error
222
224
  end
223
225
  it "body['service'] has expected additional values'" do
224
- expect(my_anno['body']['service']).to eq service
225
- expect(my_anno['body']['service']['height']).to eq 8000
226
- expect(my_anno['body']['service']['width']).to eq 6000
227
- expect(my_anno['body']['service']['tiles']).to eq tiles_val
226
+ annotation_service = my_anno['body']['service'].first
227
+ expect(annotation_service).to eq service.first
228
+ expect(annotation_service['height']).to eq 8000
229
+ expect(annotation_service['width']).to eq 6000
230
+ expect(annotation_service['tiles']).to eq tiles_val
228
231
  end
229
232
  end
230
233
  end
@@ -131,7 +131,7 @@ describe IIIF::V3::Presentation::ImageResource do
131
131
  'format' => img_mimetype,
132
132
  'height' => height,
133
133
  'width' => width,
134
- 'service' => image_v2_service
134
+ 'service' => [image_v2_service]
135
135
  })
136
136
  }
137
137
  describe 'simpler' do
@@ -146,7 +146,7 @@ describe IIIF::V3::Presentation::ImageResource do
146
146
  expect(image_object.format).to eq img_mimetype
147
147
  expect(image_object.height).to eq height
148
148
  expect(image_object.width).to eq width
149
- expect(image_object.service).to eq image_v2_service
149
+ expect(image_object.service.first).to eq image_v2_service
150
150
  end
151
151
  end
152
152
  describe 'height and width in service' do
@@ -156,27 +156,27 @@ describe IIIF::V3::Presentation::ImageResource do
156
156
  # "format": "image/jpeg",
157
157
  # "height":2000,
158
158
  # "width":1500,
159
- # "service": {
159
+ # "service": [{
160
160
  # "@context": "http://iiif.io/api/image/2/context.json",
161
161
  # "id": "http://example.org/images/book1-page2",
162
162
  # "profile": "http://iiif.io/api/image/2/level1.json",
163
163
  # "height":8000,
164
164
  # "width":6000,
165
165
  # "tiles": [{"width": 512, "scaleFactors": [1,2,4,8,16]}]
166
- # }
166
+ # }]
167
167
  # }
168
168
  let(:img_obj) {
169
169
  img = image_object
170
- img.service['height'] = 6666
171
- img.service['width'] = 9999
172
- img.service['tiles'] = [{"width" => 512, "scaleFactors" => [1,2,4,8,16]}]
170
+ img.service.first['height'] = 6666
171
+ img.service.first['width'] = 9999
172
+ img.service.first['tiles'] = [{"width" => 512, "scaleFactors" => [1,2,4,8,16]}]
173
173
  img
174
174
  }
175
175
  it 'validates' do
176
176
  expect{img_obj.validate}.not_to raise_error
177
177
  end
178
178
  it 'has expected service value' do
179
- service_obj = img_obj.service
179
+ service_obj = img_obj.service.first
180
180
  expect(service_obj.class).to eq IIIF::V3::Presentation::Service
181
181
  expect(service_obj.keys.size).to eq 7
182
182
  expect(service_obj['height']).to eq 6666
@@ -176,7 +176,7 @@ describe IIIF::V3::Presentation::Manifest do
176
176
  let!(:thumbnail_image) { IIIF::V3::Presentation::ImageResource.new({
177
177
  "id" => "https://example.org/image/iiif/abc666_05_0001/full/!400,400/0/default.jpg",
178
178
  "format" => "image/jpeg",
179
- "service" => thumbnail_image_service
179
+ "service" => [thumbnail_image_service]
180
180
  })}
181
181
  let!(:manifest_object) { described_class.new({
182
182
  "id" => "https://example.org/abc666/iiif3/manifest",
@@ -189,7 +189,7 @@ describe IIIF::V3::Presentation::Manifest do
189
189
  "items" => [canvas_object],
190
190
  "logo" => {
191
191
  "id" => "https://example.org/logo/full/400,/0/default.jpg",
192
- "service" => logo_service
192
+ "service" => [logo_service]
193
193
  },
194
194
  "seeAlso" => {
195
195
  "id" => "https://example.org/abc666.mods",
@@ -242,7 +242,7 @@ describe IIIF::V3::Presentation::Manifest do
242
242
  },
243
243
  "logo" => {
244
244
  "id" => "https://example.org/logo/full/400,/0/default.jpg",
245
- "service" => logo_service
245
+ "service" => [logo_service]
246
246
  },
247
247
  "seeAlso" => {
248
248
  "id" => "https://example.org/abc666.mods",
@@ -177,21 +177,21 @@ describe IIIF::V3::Presentation::Sequence do
177
177
  'thumbnail' => [{
178
178
  'id' => 'http://www.example.org/images/book1-page1/full/80,100/0/default.jpg',
179
179
  'type' => 'Image',
180
- 'service'=> {
180
+ 'service'=> [{
181
181
  '@context' => 'http://iiif.io/api/image/2/context.json',
182
182
  'id' => 'http://www.example.org/images/book1-page1',
183
183
  'profile' => 'http://iiif.io/api/image/2/level1.json'
184
- }
184
+ }]
185
185
  }],
186
186
  'attribution' => 'Provided by Example Organization',
187
187
  'rights' => [{'id' => 'http://www.example.org/license.html'}],
188
188
  'logo' => 'http://www.example.org/logos/institution1.jpg',
189
189
  'see_also' => 'http://www.example.org/library/catalog/book1.xml',
190
- 'service' => {
190
+ 'service' => [{
191
191
  '@context' => 'http://example.org/ns/jsonld/context.json',
192
192
  'id' => 'http://example.org/service/example',
193
193
  'profile' => 'http://example.org/docs/example-service.html'
194
- },
194
+ }],
195
195
  'related' => {
196
196
  'id' => 'http://www.example.org/videos/video-book1.mpg',
197
197
  'format' => 'video/mpeg'
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iiif-presentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Stroop
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2025-09-25 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: bundler
@@ -269,6 +270,7 @@ homepage: https://github.com/iiif/osullivan
269
270
  licenses:
270
271
  - Simplified BSD
271
272
  metadata: {}
273
+ post_install_message:
272
274
  rdoc_options: []
273
275
  require_paths:
274
276
  - lib
@@ -283,7 +285,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
285
  - !ruby/object:Gem::Version
284
286
  version: '0'
285
287
  requirements: []
286
- rubygems_version: 3.6.9
288
+ rubygems_version: 3.5.17
289
+ signing_key:
287
290
  specification_version: 4
288
291
  summary: API for working with IIIF Presentation manifests.
289
292
  test_files: