iiif_manifest 0.3.0 → 0.4.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/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +1 -0
- data/README.md +11 -1
- data/iiif_manifest.gemspec +1 -2
- data/lib/iiif_manifest.rb +0 -1
- data/lib/iiif_manifest/manifest_builder.rb +1 -0
- data/lib/iiif_manifest/manifest_builder/iiif_service.rb +197 -0
- data/lib/iiif_manifest/manifest_builder/record_property_builder.rb +39 -2
- data/lib/iiif_manifest/manifest_factory.rb +9 -3
- data/lib/iiif_manifest/manifest_service_locator.rb +21 -9
- data/lib/iiif_manifest/version.rb +1 -1
- metadata +13 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9bfc627db90ac1d23556a85e962f89447195fb7
|
4
|
+
data.tar.gz: b59e46225bae67ddfc5e2460b3672d4be113e4b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64f3b567ca52687d5fd6fe889bc085ed8850b69a343220819a5296c5ecce3d7d1a1aa7de386ca5f2ef82a3aedbac0a3b078c19c280c1e22ba7fc42effbf1234c
|
7
|
+
data.tar.gz: f550acc4ad049b10514d2c68333db4256ee0ac6e79bc4d995a9024681824bda83ac060d7fbbb9697f01e33e5eae5900c0e429212ed178133d0d9fb2f659e35d4
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -65,6 +65,7 @@ Style/Documentation:
|
|
65
65
|
- 'lib/iiif_manifest/manifest_factory.rb'
|
66
66
|
- 'lib/iiif_manifest/manifest_service_locator.rb'
|
67
67
|
- 'lib/iiif_manifest.rb'
|
68
|
+
- 'lib/iiif_manifest/manifest_builder/iiif_service.rb'
|
68
69
|
- 'spec/lib/iiif_manifest/manifest_factory_spec.rb'
|
69
70
|
|
70
71
|
# Offense count: 1
|
data/README.md
CHANGED
@@ -13,7 +13,9 @@ Additionally it ***should*** implement `#manifest_url` that shows where the mani
|
|
13
13
|
|
14
14
|
Additionally it ***should*** implement `#manifest_metadata` to provide an array containing hashes of metadata Label/Value pairs.
|
15
15
|
|
16
|
-
Additionally it ***may*** implement `#
|
16
|
+
Additionally it ***may*** implement `#search_service` to contain the url for an IIIF search api compliant search endpoint and `#autocomplete_service` to contain the url for an IIIF search api compliant autocomplete endpoint. Please note, the autocomplete service is embedded within the search service description so if an autocomplete_service is supplied without a search_service it will be ignored. The IIIF `profile` added to the service descriptions is version 0 as this is the version supported by the current version of Universal Viewer. Only include a search_service within the manifest if your application has impelmented an IIIF search service at the endpoint specified in the manifest.
|
17
|
+
|
18
|
+
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
19
|
|
18
20
|
Finally, It ***may*** implement `ranges`, which returns an array of objects which
|
19
21
|
represent a table of contents or similar structure, each of which responds to
|
@@ -50,6 +52,14 @@ For example:
|
|
50
52
|
{ "label" => "Creator", "value" => "Morrissey, Stephen Patrick" }
|
51
53
|
]
|
52
54
|
end
|
55
|
+
|
56
|
+
def search_service
|
57
|
+
"http://test.host/books/#{@id}/search"
|
58
|
+
end
|
59
|
+
|
60
|
+
def autocomplete_service
|
61
|
+
"http://test.host/books/#{@id}/autocomplete"
|
62
|
+
end
|
53
63
|
|
54
64
|
def sequence_rendering
|
55
65
|
[{"@id" => "http://test.host/file_set/id/download", "format" => "application/pdf", "label" => "Download"}]
|
data/iiif_manifest.gemspec
CHANGED
@@ -18,12 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_dependency 'activesupport', '>= 4'
|
21
|
-
spec.add_dependency 'iiif-presentation', '~> 0.2.0'
|
22
21
|
|
23
22
|
spec.add_development_dependency 'bundler', '~> 1.11'
|
23
|
+
spec.add_development_dependency 'pry-byebug'
|
24
24
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
25
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
26
|
spec.add_development_dependency 'rubocop'
|
27
27
|
spec.add_development_dependency 'rubocop-rspec'
|
28
|
-
spec.add_development_dependency 'pry-byebug'
|
29
28
|
end
|
data/lib/iiif_manifest.rb
CHANGED
@@ -0,0 +1,197 @@
|
|
1
|
+
module IIIFManifest
|
2
|
+
class ManifestBuilder
|
3
|
+
class IIIFService
|
4
|
+
attr_reader :inner_hash
|
5
|
+
def initialize
|
6
|
+
@inner_hash = initial_attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
delegate :[]=, :[], :as_json, :to_json, :has_key?, to: :inner_hash
|
10
|
+
|
11
|
+
def initial_attributes
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class IIIFManifest < IIIFService
|
17
|
+
def label
|
18
|
+
inner_hash['label']
|
19
|
+
end
|
20
|
+
|
21
|
+
def label=(label)
|
22
|
+
inner_hash['label'] = label
|
23
|
+
end
|
24
|
+
|
25
|
+
def description=(description)
|
26
|
+
return unless description.present?
|
27
|
+
inner_hash['description'] = description
|
28
|
+
end
|
29
|
+
|
30
|
+
def viewing_hint=(viewing_hint)
|
31
|
+
return unless viewing_hint.present?
|
32
|
+
inner_hash['viewingHint'] = viewing_hint
|
33
|
+
end
|
34
|
+
|
35
|
+
def viewing_direction=(viewing_direction)
|
36
|
+
return unless viewing_direction.present?
|
37
|
+
inner_hash['viewingDirection'] = viewing_direction
|
38
|
+
end
|
39
|
+
|
40
|
+
def viewingDirection
|
41
|
+
inner_hash['viewingDirection']
|
42
|
+
end
|
43
|
+
|
44
|
+
def sequences
|
45
|
+
inner_hash['sequences'] || []
|
46
|
+
end
|
47
|
+
|
48
|
+
def sequences=(sequences)
|
49
|
+
inner_hash['sequences'] = sequences
|
50
|
+
end
|
51
|
+
|
52
|
+
def metadata=(metadata)
|
53
|
+
inner_hash['metadata'] = metadata
|
54
|
+
end
|
55
|
+
|
56
|
+
def service
|
57
|
+
inner_hash['service'] || []
|
58
|
+
end
|
59
|
+
|
60
|
+
def service=(service)
|
61
|
+
inner_hash['service'] = service
|
62
|
+
end
|
63
|
+
|
64
|
+
def see_also=(see_also)
|
65
|
+
inner_hash['seeAlso'] = see_also
|
66
|
+
end
|
67
|
+
|
68
|
+
def license=(license)
|
69
|
+
inner_hash['license'] = license
|
70
|
+
end
|
71
|
+
|
72
|
+
def initial_attributes
|
73
|
+
{
|
74
|
+
'@context' => 'http://iiif.io/api/presentation/2/context.json',
|
75
|
+
'@type' => 'sc:Manifest'
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
class Collection < IIIFManifest
|
80
|
+
def initial_attributes
|
81
|
+
{
|
82
|
+
'@context' => 'http://iiif.io/api/presentation/2/context.json',
|
83
|
+
'@type' => 'sc:Collection'
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Sequence < IIIFService
|
89
|
+
def canvases
|
90
|
+
inner_hash['canvases'] || []
|
91
|
+
end
|
92
|
+
|
93
|
+
def canvases=(canvases)
|
94
|
+
inner_hash['canvases'] = canvases
|
95
|
+
end
|
96
|
+
|
97
|
+
def initial_attributes
|
98
|
+
{
|
99
|
+
'@type' => 'sc:Sequence'
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Canvas < IIIFService
|
105
|
+
def label=(label)
|
106
|
+
inner_hash['label'] = label
|
107
|
+
end
|
108
|
+
|
109
|
+
def images
|
110
|
+
inner_hash['images'] || []
|
111
|
+
end
|
112
|
+
|
113
|
+
def images=(images)
|
114
|
+
inner_hash['images'] = images
|
115
|
+
end
|
116
|
+
|
117
|
+
def initial_attributes
|
118
|
+
{
|
119
|
+
'@type' => 'sc:Canvas'
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class Range < IIIFService
|
125
|
+
def initial_attributes
|
126
|
+
{
|
127
|
+
'@type' => 'sc:Range'
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class Resource < IIIFService
|
133
|
+
def service=(service)
|
134
|
+
inner_hash['service'] = service
|
135
|
+
end
|
136
|
+
|
137
|
+
def initial_attributes
|
138
|
+
{
|
139
|
+
'@type' => 'sc:Range'
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Annotation < IIIFService
|
145
|
+
def resource=(resource)
|
146
|
+
inner_hash['resource'] = resource
|
147
|
+
end
|
148
|
+
|
149
|
+
def resource
|
150
|
+
inner_hash['resource']
|
151
|
+
end
|
152
|
+
|
153
|
+
def initial_attributes
|
154
|
+
{
|
155
|
+
'@type' => 'oa:Annotation',
|
156
|
+
'motivation' => 'sc:painting'
|
157
|
+
}
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class SearchService < IIIFService
|
162
|
+
def service=(service)
|
163
|
+
inner_hash['service'] = service
|
164
|
+
end
|
165
|
+
|
166
|
+
def search_service=(search_service)
|
167
|
+
inner_hash['@id'] = search_service
|
168
|
+
end
|
169
|
+
|
170
|
+
def initial_attributes
|
171
|
+
{
|
172
|
+
'@context' => 'http://iiif.io/api/search/0/context.json',
|
173
|
+
'profile' => 'http://iiif.io/api/search/0/search',
|
174
|
+
'label' => 'Search within this manifest'
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class AutocompleteService < IIIFService
|
180
|
+
def autocomplete_service
|
181
|
+
inner_hash['@id']
|
182
|
+
end
|
183
|
+
|
184
|
+
def autocomplete_service=(autocomplete_service)
|
185
|
+
inner_hash['@id'] = autocomplete_service
|
186
|
+
end
|
187
|
+
|
188
|
+
def initial_attributes
|
189
|
+
{
|
190
|
+
'profile' => 'http://iiif.io/api/search/0/autocomplete',
|
191
|
+
'label' => 'Get suggested words in this manifest'
|
192
|
+
}
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -1,19 +1,25 @@
|
|
1
1
|
module IIIFManifest
|
2
2
|
class ManifestBuilder
|
3
3
|
class RecordPropertyBuilder
|
4
|
-
attr_reader :record, :
|
5
|
-
def initialize(record)
|
4
|
+
attr_reader :record, :iiif_search_service_factory, :iiif_autocomplete_service_factory
|
5
|
+
def initialize(record, iiif_search_service_factory:, iiif_autocomplete_service_factory:)
|
6
6
|
@record = record
|
7
|
+
@iiif_search_service_factory = iiif_search_service_factory
|
8
|
+
@iiif_autocomplete_service_factory = iiif_autocomplete_service_factory
|
7
9
|
end
|
8
10
|
|
11
|
+
# rubocop:disable Metrics/AbcSize
|
9
12
|
def apply(manifest)
|
10
13
|
manifest['@id'] = record.manifest_url.to_s
|
11
14
|
manifest.label = record.to_s
|
12
15
|
manifest.description = record.description
|
13
16
|
manifest.viewing_hint = viewing_hint if viewing_hint.present?
|
17
|
+
manifest.viewing_direction = viewing_direction if viewing_direction.present?
|
14
18
|
manifest.metadata = record.manifest_metadata if valid_metadata?
|
19
|
+
manifest.service = services if search_service.present?
|
15
20
|
manifest
|
16
21
|
end
|
22
|
+
# rubocop:enable Metrics/AbcSize
|
17
23
|
|
18
24
|
private
|
19
25
|
|
@@ -21,6 +27,37 @@ module IIIFManifest
|
|
21
27
|
(record.respond_to?(:viewing_hint) && record.send(:viewing_hint))
|
22
28
|
end
|
23
29
|
|
30
|
+
def viewing_direction
|
31
|
+
(record.respond_to?(:viewing_direction) && record.send(:viewing_direction))
|
32
|
+
end
|
33
|
+
|
34
|
+
def autocomplete_service
|
35
|
+
(record.respond_to?(:autocomplete_service) && record.send(:autocomplete_service))
|
36
|
+
end
|
37
|
+
|
38
|
+
def search_service
|
39
|
+
(record.respond_to?(:search_service) && record.send(:search_service))
|
40
|
+
end
|
41
|
+
|
42
|
+
def iiif_search_service
|
43
|
+
@iiif_search_service ||= iiif_search_service_factory.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def iiif_autocomplete_service
|
47
|
+
@iiif_autocomplete_service ||= iiif_autocomplete_service_factory.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# Build services. Currently supported:
|
51
|
+
# search_service, with (optional) embedded autocomplete service
|
52
|
+
#
|
53
|
+
# @return [Array] array of services
|
54
|
+
def services
|
55
|
+
iiif_search_service.search_service = search_service
|
56
|
+
iiif_autocomplete_service.autocomplete_service = autocomplete_service
|
57
|
+
iiif_search_service.service = iiif_autocomplete_service if autocomplete_service.present?
|
58
|
+
[iiif_search_service]
|
59
|
+
end
|
60
|
+
|
24
61
|
# Validate manifest_metadata against the IIIF spec format for metadata
|
25
62
|
#
|
26
63
|
# @return [Boolean]
|
@@ -16,15 +16,21 @@ module IIIFManifest
|
|
16
16
|
|
17
17
|
def new(work)
|
18
18
|
if !work.work_presenters.empty?
|
19
|
-
if work.file_set_presenters.empty?
|
19
|
+
if sammelband?(work) || !work.file_set_presenters.empty?
|
20
|
+
sammelband_manifest_builder.new(work)
|
21
|
+
elsif work.file_set_presenters.empty?
|
20
22
|
work = IIIFCollection.new(work)
|
21
23
|
collection_manifest_builder.new(work)
|
22
|
-
elsif !work.file_set_presenters.empty?
|
23
|
-
sammelband_manifest_builder.new(work)
|
24
24
|
end
|
25
25
|
else
|
26
26
|
manifest_builder.new(work)
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def sammelband?(work)
|
33
|
+
work.respond_to?(:sammelband?) && work.sammelband?
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
@@ -68,7 +68,7 @@ module IIIFManifest
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def iiif_collection_factory
|
71
|
-
|
71
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Collection
|
72
72
|
end
|
73
73
|
|
74
74
|
def composite_builder
|
@@ -80,7 +80,11 @@ module IIIFManifest
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def record_property_builder
|
83
|
-
|
83
|
+
InjectedFactory.new(
|
84
|
+
ManifestBuilder::RecordPropertyBuilder,
|
85
|
+
iiif_search_service_factory: iiif_search_service_factory,
|
86
|
+
iiif_autocomplete_service_factory: iiif_autocomplete_service_factory
|
87
|
+
)
|
84
88
|
end
|
85
89
|
|
86
90
|
def structure_builder
|
@@ -108,7 +112,7 @@ module IIIFManifest
|
|
108
112
|
end
|
109
113
|
|
110
114
|
def sequence_factory
|
111
|
-
|
115
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Sequence
|
112
116
|
end
|
113
117
|
|
114
118
|
def canvas_builder_factory
|
@@ -157,27 +161,35 @@ module IIIFManifest
|
|
157
161
|
end
|
158
162
|
|
159
163
|
def iiif_service_factory
|
160
|
-
|
164
|
+
IIIFManifest::ManifestBuilder::IIIFService
|
161
165
|
end
|
162
166
|
|
163
167
|
def iiif_resource_factory
|
164
|
-
|
168
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Resource
|
165
169
|
end
|
166
170
|
|
167
171
|
def iiif_annotation_factory
|
168
|
-
|
172
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Annotation
|
169
173
|
end
|
170
174
|
|
171
175
|
def iiif_manifest_factory
|
172
|
-
|
176
|
+
IIIFManifest::ManifestBuilder::IIIFManifest
|
173
177
|
end
|
174
178
|
|
175
179
|
def iiif_canvas_factory
|
176
|
-
|
180
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Canvas
|
177
181
|
end
|
178
182
|
|
179
183
|
def iiif_range_factory
|
180
|
-
|
184
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::Range
|
185
|
+
end
|
186
|
+
|
187
|
+
def iiif_search_service_factory
|
188
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::SearchService
|
189
|
+
end
|
190
|
+
|
191
|
+
def iiif_autocomplete_service_factory
|
192
|
+
IIIFManifest::ManifestBuilder::IIIFManifest::AutocompleteService
|
181
193
|
end
|
182
194
|
end
|
183
195
|
|
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.4.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:
|
12
|
+
date: 2018-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -26,33 +26,33 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '4'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: bundler
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
35
|
-
type: :
|
34
|
+
version: '1.11'
|
35
|
+
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: '1.11'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
43
|
+
name: pry-byebug
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
48
|
+
version: '0'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: rake
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,20 +109,6 @@ dependencies:
|
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
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'
|
126
112
|
description: IIIF http://iiif.io/ defines an API for presenting related images in
|
127
113
|
a viewer. This transforms Hydra::Works objects into that format usable by players
|
128
114
|
such as http://universalviewer.io/
|
@@ -156,6 +142,7 @@ files:
|
|
156
142
|
- lib/iiif_manifest/manifest_builder/composite_builder.rb
|
157
143
|
- lib/iiif_manifest/manifest_builder/composite_builder_factory.rb
|
158
144
|
- lib/iiif_manifest/manifest_builder/deep_canvas_builder_factory.rb
|
145
|
+
- lib/iiif_manifest/manifest_builder/iiif_service.rb
|
159
146
|
- lib/iiif_manifest/manifest_builder/image_builder.rb
|
160
147
|
- lib/iiif_manifest/manifest_builder/image_service_builder.rb
|
161
148
|
- lib/iiif_manifest/manifest_builder/record_property_builder.rb
|
@@ -184,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
171
|
version: '0'
|
185
172
|
requirements: []
|
186
173
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.6.
|
174
|
+
rubygems_version: 2.6.14
|
188
175
|
signing_key:
|
189
176
|
specification_version: 4
|
190
177
|
summary: Generate IIIF presentation manifests for Hydra::Works
|