wax_iiif 0.0.2 → 0.1.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 +1 -0
- data/.rubocop.yml +25 -0
- data/.travis.yml +2 -2
- data/Gemfile +3 -2
- data/README.md +4 -4
- data/lib/wax_iiif.rb +34 -44
- data/lib/wax_iiif/base_properties.rb +90 -0
- data/lib/wax_iiif/builder.rb +252 -0
- data/lib/wax_iiif/collection.rb +58 -0
- data/lib/{iiif_s3 → wax_iiif}/config.rb +46 -60
- data/lib/{iiif_s3 → wax_iiif}/errors.rb +6 -12
- data/lib/{iiif_s3 → wax_iiif}/full_image.rb +3 -8
- data/lib/wax_iiif/image_info.rb +89 -0
- data/lib/{iiif_s3 → wax_iiif}/image_record.rb +48 -63
- data/lib/{iiif_s3 → wax_iiif}/image_tile.rb +8 -14
- data/lib/{iiif_s3 → wax_iiif}/image_variant.rb +20 -38
- data/lib/wax_iiif/manifest.rb +151 -0
- data/lib/{iiif_s3 → wax_iiif}/thumbnail.rb +5 -9
- data/lib/{iiif_s3 → wax_iiif}/utilities.rb +5 -5
- data/lib/{iiif_s3 → wax_iiif}/utilities/helpers.rb +18 -48
- data/lib/{iiif_s3 → wax_iiif}/utilities/pdf_splitter.rb +20 -23
- data/spec/base_properties_spec.rb +8 -12
- data/spec/shared_contexts.rb +28 -92
- data/spec/spec_helper.rb +3 -3
- data/spec/wax_iiif/builder_spec.rb +143 -0
- data/spec/wax_iiif/collection_spec.rb +53 -0
- data/spec/wax_iiif/config_spec.rb +15 -0
- data/spec/wax_iiif/image_info_spec.rb +57 -0
- data/spec/wax_iiif/image_record_spec.rb +82 -0
- data/spec/wax_iiif/image_variant_spec.rb +66 -0
- data/spec/wax_iiif/manifest_spec.rb +97 -0
- data/spec/wax_iiif/utilities/pdf_splitter_spec.rb +14 -0
- data/wax_iiif.gemspec +15 -19
- metadata +52 -97
- data/Guardfile +0 -10
- data/Rakefile +0 -24
- data/lib/iiif_s3/base_properties.rb +0 -95
- data/lib/iiif_s3/builder.rb +0 -241
- data/lib/iiif_s3/collection.rb +0 -61
- data/lib/iiif_s3/image_info.rb +0 -96
- data/lib/iiif_s3/manifest.rb +0 -151
- data/lib/iiif_s3/version.rb +0 -5
- data/spec/iiif_s3/builder_spec.rb +0 -152
- data/spec/iiif_s3/collection_spec.rb +0 -68
- data/spec/iiif_s3/config_spec.rb +0 -15
- data/spec/iiif_s3/image_info_spec.rb +0 -57
- data/spec/iiif_s3/image_record_spec.rb +0 -96
- data/spec/iiif_s3/image_variant_spec.rb +0 -68
- data/spec/iiif_s3/manifest_spec.rb +0 -97
- data/spec/iiif_s3/utilities/pdf_splitter_spec.rb +0 -17
- data/test.rb +0 -77
data/Guardfile
DELETED
data/Rakefile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
3
|
-
require 'yard'
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
|
7
|
-
YARD::Rake::YardocTask.new do |t|
|
8
|
-
t.files = ['lib/**/*.rb'] # optional
|
9
|
-
t.stats_options = ['--list-undoc'] # optional
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Clear the screen"
|
13
|
-
task :cls do
|
14
|
-
puts "Clearing the Screen \033c"
|
15
|
-
end
|
16
|
-
|
17
|
-
task :full do
|
18
|
-
ENV["TEST_INTERNET_CONNECTIVITY"] = "yes"
|
19
|
-
ENV["SKIP_EXPENSIVE_TESTS"] = nil
|
20
|
-
end
|
21
|
-
|
22
|
-
task :default => [:cls, :spec, :yard]
|
23
|
-
|
24
|
-
task :full_test => [:full, :default]
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require_relative "utilities"
|
2
|
-
module IiifS3
|
3
|
-
|
4
|
-
# Module BaseProperties provides the set of properties that are shared across
|
5
|
-
# all IIIF types. It is not a comprehensive list (yet), but it does handle
|
6
|
-
# most of the shared types. It does not include any types that have class-based
|
7
|
-
# restrictions.
|
8
|
-
#
|
9
|
-
# It also performs some basic sanity checking on (some of) the fields, and
|
10
|
-
# provides utility classes that are applicable across the fields.
|
11
|
-
#
|
12
|
-
# @todo Add within, service, seeAlso, viewingHint fields
|
13
|
-
#
|
14
|
-
# @author David Newbury <david.newbury@gmail.com>
|
15
|
-
#
|
16
|
-
module BaseProperties
|
17
|
-
include Utilities::Helpers
|
18
|
-
|
19
|
-
|
20
|
-
# @!attribute [rw] label
|
21
|
-
# @return [String] The human-readable label for this record
|
22
|
-
attr_accessor :label
|
23
|
-
# @!attribute [r] id
|
24
|
-
# @return [String] The URI for this record
|
25
|
-
attr_reader :id
|
26
|
-
# @!attribute [rw] description
|
27
|
-
# @return [String] The long-form description of this record
|
28
|
-
attr_accessor :description
|
29
|
-
# @!attribute [rw] metadata
|
30
|
-
# @return [Hash] A set of key/value pairs describing additional metadata for the object.
|
31
|
-
attr_accessor :metadata
|
32
|
-
# @!attribute [rw] attribution
|
33
|
-
# @return [String] a human-readable label, typically used for attribution or credit.
|
34
|
-
attr_accessor :attribution
|
35
|
-
# @!attribute [rw] logo
|
36
|
-
# @return [String] The URI to an image for the logo of the institution associated with this record.
|
37
|
-
attr_accessor :logo
|
38
|
-
# @!attribute [rw] license
|
39
|
-
# @return [String] The URI to a resource that describes the license or rights statement associated.
|
40
|
-
attr_accessor :license
|
41
|
-
# @!attribute [rw] related
|
42
|
-
# @return [String, Array<String>] The URI to related resources. Can be both a string or an array
|
43
|
-
attr_accessor :related
|
44
|
-
|
45
|
-
# The type of resource provided by this record.
|
46
|
-
#
|
47
|
-
# @return [String] The type of record
|
48
|
-
def type
|
49
|
-
self.class::TYPE
|
50
|
-
end
|
51
|
-
|
52
|
-
# Set the unique id for this record.
|
53
|
-
# This will automatically append the defined prefixes and suffixes.
|
54
|
-
#
|
55
|
-
# @param [String] _id The unique portion of this ID
|
56
|
-
# @return [string] The URI for this record
|
57
|
-
def id=(_id)
|
58
|
-
@id = generate_id(_id)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Return the base data structure for this record as a Hash
|
62
|
-
# This will be in IIIF format, and should convert to JSON as JSON-LD nicely.
|
63
|
-
#
|
64
|
-
# @return [Hash] The base properties of this record
|
65
|
-
def base_properties
|
66
|
-
obj = {
|
67
|
-
"@context" => PRESENTATION_CONTEXT,
|
68
|
-
"@id" => self.id,
|
69
|
-
"@type" => self.type,
|
70
|
-
"label" => self.label
|
71
|
-
}
|
72
|
-
obj["attribution"] = self.attribution if self.attribution
|
73
|
-
obj["logo"] = self.logo if self.logo
|
74
|
-
obj["description"] = self.description if self.description
|
75
|
-
obj["attribution"] = self.attribution if self.attribution
|
76
|
-
obj["license"] = self.license if self.license
|
77
|
-
obj["related"] = self.related if self.related
|
78
|
-
obj["metadata"] = self.metadata if self.metadata
|
79
|
-
|
80
|
-
obj
|
81
|
-
end
|
82
|
-
|
83
|
-
# Save the JSON representation of this record to disk and to S3 (if enabled).
|
84
|
-
#
|
85
|
-
# @return [Void]
|
86
|
-
def save
|
87
|
-
save_to_disk(JSON.parse(self.to_json))
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
protected
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
data/lib/iiif_s3/builder.rb
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
require_relative "utilities"
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
module IiifS3
|
5
|
-
class Builder
|
6
|
-
|
7
|
-
include Utilities::Helpers
|
8
|
-
|
9
|
-
HEADER_VAL = 'filename'
|
10
|
-
|
11
|
-
#
|
12
|
-
# @!attribute [r] data
|
13
|
-
# @return [Array<Hash>] The raw data computed for the given set of images
|
14
|
-
attr_reader :data
|
15
|
-
|
16
|
-
#
|
17
|
-
# @!attribute [r] manifests
|
18
|
-
# @return [Array<Hash>] The manifest hashes for this configuration
|
19
|
-
attr_accessor :manifests
|
20
|
-
|
21
|
-
# @!attribute [r] config
|
22
|
-
# @return [IiifS3::Config] The configuration object
|
23
|
-
attr_reader :config
|
24
|
-
|
25
|
-
# Initialize the builder.
|
26
|
-
#
|
27
|
-
# @param [Hash] config an optional configuration object.
|
28
|
-
# @see IiifS3::Config
|
29
|
-
# @return [Void]
|
30
|
-
#
|
31
|
-
def initialize(config = {})
|
32
|
-
@manifests = []
|
33
|
-
@config = IiifS3::Config.new(config)
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
# Load data into the IIIF builder.
|
39
|
-
#
|
40
|
-
# This will load the data, perform some basic verifications on it, and sort
|
41
|
-
# it into proper order.
|
42
|
-
#
|
43
|
-
# @param [Array<ImageRecord>, ImageRecord] data
|
44
|
-
# Either a single ImageRecord or an Array of ImageRecords.
|
45
|
-
# @raise [IiifS3::Error::InvalidImageData] if any of the data does
|
46
|
-
# not pass the validation checks
|
47
|
-
#
|
48
|
-
# @return [Void]
|
49
|
-
#
|
50
|
-
def load(data)
|
51
|
-
@data = [data].flatten # handle hashes and arrays of hashes
|
52
|
-
|
53
|
-
# validate
|
54
|
-
@data.each do |image_record|
|
55
|
-
raise IiifS3::Error::InvalidImageData, "Image record #{image_record.inspect} is not an ImageRecord" unless image_record.is_a? ImageRecord
|
56
|
-
raise IiifS3::Error::InvalidImageData, "Image record #{image_record.inspect} does not have an ID and/or a page number" if image_record.id.nil? || image_record.page_number.nil?
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
# Take the loaded data and generate all the files.
|
63
|
-
#
|
64
|
-
# @param [Boolean] force_image_generation Generate images even if they already exist
|
65
|
-
#
|
66
|
-
# @return [Void]
|
67
|
-
#
|
68
|
-
def process_data(force_image_generation=false)
|
69
|
-
return nil if @data.nil? # do nothing without data.
|
70
|
-
@manifests = []
|
71
|
-
|
72
|
-
resources = {}
|
73
|
-
@data.each do |image_record|
|
74
|
-
|
75
|
-
# image generation
|
76
|
-
#
|
77
|
-
# It attempts to load the info files and skip generation — not currently working.
|
78
|
-
info_file = image_info_file_name(image_record)
|
79
|
-
if (File.exist?(info_file) && !force_image_generation)
|
80
|
-
puts "skipping #{info_file}" if @config.verbose?
|
81
|
-
image_record.variants = load_variants(info_file)
|
82
|
-
else
|
83
|
-
image_record.variants = generate_variants(image_record, @config)
|
84
|
-
generate_tiles(image_record, @config)
|
85
|
-
generate_image_json(image_record, @config)
|
86
|
-
end
|
87
|
-
# Save the image info for the manifest
|
88
|
-
resources[image_record.id] ||= []
|
89
|
-
resources[image_record.id].push image_record
|
90
|
-
end
|
91
|
-
|
92
|
-
# Generate the manifests
|
93
|
-
resources.each do |key, val|
|
94
|
-
manifests.push generate_manifest(val, @config)
|
95
|
-
end
|
96
|
-
|
97
|
-
generate_collection
|
98
|
-
end
|
99
|
-
|
100
|
-
def generate_collection(label="top")
|
101
|
-
collection = Collection.new(label,@config)
|
102
|
-
manifests.each{|m| collection.add_manifest(m)}
|
103
|
-
collection.save
|
104
|
-
end
|
105
|
-
|
106
|
-
# Creates the required directories for exporting to the file system.
|
107
|
-
#
|
108
|
-
# @return [Void]
|
109
|
-
def create_build_directories
|
110
|
-
root_dir = generate_build_location("")
|
111
|
-
Dir.mkdir root_dir unless Dir.exists?(root_dir)
|
112
|
-
img_dir = generate_image_location("","").split("/")[0...-1].join("/")
|
113
|
-
Dir.mkdir img_dir unless Dir.exists?(img_dir)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Load data into the IIIF server from a CSV
|
117
|
-
#
|
118
|
-
# @param [String] csv_path Path to the CSV file containing the image data
|
119
|
-
#
|
120
|
-
# @return [Void]
|
121
|
-
# @todo Fix this to use the correct data format!
|
122
|
-
#
|
123
|
-
def load_csv(csv_path)
|
124
|
-
raise Error::InvalidCSV unless File.exist? csv_path
|
125
|
-
begin
|
126
|
-
vals = CSV.read(csv_path)
|
127
|
-
rescue CSV::MalformedCSVError
|
128
|
-
raise Error::InvalidCSV
|
129
|
-
end
|
130
|
-
|
131
|
-
raise Error::BlankCSV if vals.length == 0
|
132
|
-
raise Error::InvalidCSV if vals[0].length != 3
|
133
|
-
|
134
|
-
# remove optional header
|
135
|
-
vals.shift if vals[0][0] == HEADER_VAL
|
136
|
-
|
137
|
-
@data = vals.collect do |data|
|
138
|
-
{
|
139
|
-
"image_path" => data[0],
|
140
|
-
"id" => data[1],
|
141
|
-
"label" => data[2]
|
142
|
-
}
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
protected
|
147
|
-
|
148
|
-
#----------------------------------------------------------------
|
149
|
-
def load_variants(path)
|
150
|
-
|
151
|
-
data = JSON.parse File.read(path)
|
152
|
-
id = data["@id"]
|
153
|
-
w = data["width"]
|
154
|
-
h = data["height"]
|
155
|
-
thumb_size = data["sizes"].find{|a| a["width"] == config.thumbnail_size || a["height"] == config.thumbnail_size}
|
156
|
-
thumb_w = thumb_size["width"]
|
157
|
-
thumb_h = thumb_size["height"]
|
158
|
-
full_url = "#{id}/full/full/0/default.jpg"
|
159
|
-
thumb_url = "#{id}/full/#{thumb_w},/0/default.jpg"
|
160
|
-
full = FakeImageVariant.new( id,w, h,full_url, "image/jpeg")
|
161
|
-
thumbnail = FakeImageVariant.new( id, thumb_w, thumb_h, thumb_url, "image/jpeg")
|
162
|
-
return {"full" => full, "thumbnail" => thumbnail}
|
163
|
-
end
|
164
|
-
|
165
|
-
def generate_tiles(data, config)
|
166
|
-
width = data.variants["full"].width
|
167
|
-
tile_width = config.tile_width
|
168
|
-
height = data.variants["full"].height
|
169
|
-
tiles = []
|
170
|
-
config.tile_scale_factors.each do |s|
|
171
|
-
(0..(height*1.0/(tile_width*s)).floor).each do |tileY|
|
172
|
-
(0..(width*1.0/(tile_width*s)).floor).each do |tileX|
|
173
|
-
tile = {
|
174
|
-
scale_factor: s,
|
175
|
-
xpos: tileX,
|
176
|
-
ypos: tileY,
|
177
|
-
x: tileX * tile_width * s,
|
178
|
-
y: tileY * tile_width * s,
|
179
|
-
width: tile_width * s,
|
180
|
-
height: tile_width * s,
|
181
|
-
xSize: tile_width,
|
182
|
-
ySize: tile_width
|
183
|
-
}
|
184
|
-
if (tile[:x] + tile[:width] > width)
|
185
|
-
tile[:width] = width - tile[:x]
|
186
|
-
tile[:xSize] = (tile[:width]/(s*1.0)).ceil
|
187
|
-
end
|
188
|
-
if (tile[:y] + tile[:height] > height)
|
189
|
-
tile[:height] = height - tile[:y]
|
190
|
-
tile[:ySize] = (tile[:height]/(s*1.0)).ceil
|
191
|
-
end
|
192
|
-
tiles.push(tile)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
tiles.each do |tile|
|
197
|
-
ImageTile.new(data, @config, tile)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def image_info_file_name(data)
|
202
|
-
"#{generate_image_location(data.id,data.page_number)}/info.json"
|
203
|
-
end
|
204
|
-
|
205
|
-
def generate_image_json(data, config)
|
206
|
-
filename = image_info_file_name(data)
|
207
|
-
info = ImageInfo.new(data.variants["full"].id, data.variants ,config.tile_width, config.tile_scale_factors)
|
208
|
-
|
209
|
-
puts "writing #{filename}" if config.verbose?
|
210
|
-
Pathname.new(Pathname.new(filename).dirname).mkpath
|
211
|
-
File.open(filename, "w") do |file|
|
212
|
-
file.puts info.to_json
|
213
|
-
end
|
214
|
-
if @config.upload_to_s3
|
215
|
-
add_file_to_s3(filename)
|
216
|
-
add_default_redirect(filename)
|
217
|
-
end
|
218
|
-
return info
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
def generate_manifest(data, config)
|
223
|
-
m = Manifest.new(data, config)
|
224
|
-
m.save_all_files_to_disk
|
225
|
-
return m
|
226
|
-
end
|
227
|
-
|
228
|
-
|
229
|
-
def generate_variants(data, config)
|
230
|
-
obj = {
|
231
|
-
"full" => FullImage.new(data, config),
|
232
|
-
"thumbnail" => Thumbnail.new(data, config)
|
233
|
-
}
|
234
|
-
|
235
|
-
config.variants.each do |key,image_size|
|
236
|
-
obj[key] = ImageVariant.new(data, config, image_size)
|
237
|
-
end
|
238
|
-
return obj
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
data/lib/iiif_s3/collection.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module IiifS3
|
2
|
-
|
3
|
-
#
|
4
|
-
# Class Collection is an abstraction over the IIIF Collection, which is an aggregation
|
5
|
-
# of IIIF manifests.
|
6
|
-
#
|
7
|
-
# @author David Newbury <david.newbury@gmail.com>
|
8
|
-
#
|
9
|
-
class Collection
|
10
|
-
|
11
|
-
# @return [String] The IIIF Type for collections
|
12
|
-
TYPE = "sc:Collection"
|
13
|
-
|
14
|
-
include BaseProperties
|
15
|
-
attr_reader :collections, :manifests
|
16
|
-
|
17
|
-
def initialize(label, config, name="top")
|
18
|
-
raise IiifS3::Error::MissingCollectionName if label.nil? || label.empty?
|
19
|
-
@config = config
|
20
|
-
@manifests = []
|
21
|
-
@collections = []
|
22
|
-
self.label = label
|
23
|
-
self.id = "collection/#{name}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def add_collection(collection)
|
27
|
-
raise IiifS3::Error::NotACollection unless collection.respond_to?(:type) && collection.type == Collection::TYPE
|
28
|
-
@collections.push(collection)
|
29
|
-
end
|
30
|
-
|
31
|
-
def add_manifest(manifest)
|
32
|
-
raise IiifS3::Error::NotAManifest unless manifest.respond_to?(:type) && manifest.type == Manifest::TYPE
|
33
|
-
@manifests.push(manifest)
|
34
|
-
end
|
35
|
-
|
36
|
-
# The JSON representation of this collection in the IIIF-expected format
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# @return [String] The JSON representation as a string
|
40
|
-
#
|
41
|
-
def to_json
|
42
|
-
obj = base_properties
|
43
|
-
obj["collections"] = collect_object(collections) unless collections.empty?
|
44
|
-
obj["manifests"] = collect_object(manifests) unless manifests.empty?
|
45
|
-
JSON.pretty_generate obj
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def collect_object(things)
|
51
|
-
things.collect do |thing|
|
52
|
-
{
|
53
|
-
"@id" => thing.id,
|
54
|
-
"@type" => thing.type,
|
55
|
-
"label" => thing.label
|
56
|
-
}
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
data/lib/iiif_s3/image_info.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
module IiifS3
|
2
|
-
|
3
|
-
#
|
4
|
-
# Class ImageInfo is a data object for the JSON representation of the image.
|
5
|
-
#
|
6
|
-
# It is designed to support the http://iiif.io/api/image/2.0/#image-information spec.
|
7
|
-
class ImageInfo
|
8
|
-
|
9
|
-
attr_accessor :id
|
10
|
-
attr_accessor :width
|
11
|
-
attr_accessor :height
|
12
|
-
attr_accessor :tile_width
|
13
|
-
attr_accessor :tile_scale_factors
|
14
|
-
|
15
|
-
def initialize(uri, variants, tile_width= nil, tile_scale_factors = nil)
|
16
|
-
|
17
|
-
raise IiifS3::Error::InvalidImageData, "No full variant provided: variants: #{variants}" unless variants["full"]
|
18
|
-
raise IiifS3::Error::InvalidImageData, "No thumbnail variant provided: variants: #{variants}" unless variants["thumbnail"]
|
19
|
-
raise IiifS3::Error::InvalidImageData, "No URI was provided for this image!" if uri.nil?
|
20
|
-
|
21
|
-
@id = uri
|
22
|
-
full = variants["full"]
|
23
|
-
@variants = variants
|
24
|
-
@width = full.width
|
25
|
-
@height = full.height
|
26
|
-
@tile_width = tile_width
|
27
|
-
@tile_scale_factors = tile_scale_factors
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Hash] a collection of valid sizes based on the available image variants
|
31
|
-
#
|
32
|
-
def sizes
|
33
|
-
@variants.collect do |name,obj|
|
34
|
-
{"width" => obj.width, "height" => obj.height}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# The hash of tile information, or nil if the information does not exist.
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# @return [Hash, nil] A hash of the tile metadata properly formatted for IIIF JSON.
|
42
|
-
#
|
43
|
-
def tiles
|
44
|
-
return nil if @tile_scale_factors.nil? || @tile_scale_factors.empty?
|
45
|
-
|
46
|
-
return [{
|
47
|
-
"width" => @tile_width,
|
48
|
-
"scaleFactors" => @tile_scale_factors
|
49
|
-
}]
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
# Generate the JSON data for this image in the IIIF-expected format.
|
54
|
-
#
|
55
|
-
#
|
56
|
-
# @return [String] the JSON representation of this image
|
57
|
-
#
|
58
|
-
def to_json
|
59
|
-
obj = {
|
60
|
-
"@context" => context,
|
61
|
-
"@id" => URI.escape(id),
|
62
|
-
"protocol" => protocol,
|
63
|
-
"width" => width,
|
64
|
-
"height" => height,
|
65
|
-
"sizes" => sizes,
|
66
|
-
"profile" => profile,
|
67
|
-
}
|
68
|
-
obj["tiles"] = tiles unless tiles.nil?
|
69
|
-
obj["profile"] = profile
|
70
|
-
obj["service"] = service unless service.nil?
|
71
|
-
JSON.pretty_generate obj
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [String] The IIIF context for this image
|
75
|
-
def context
|
76
|
-
IiifS3::IMAGE_CONTEXT
|
77
|
-
end
|
78
|
-
|
79
|
-
# @return [String] The IIIF protocol for this image
|
80
|
-
def protocol
|
81
|
-
IiifS3::IMAGE_PROTOCOL
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [String] The IIIF profile this image supports
|
85
|
-
def profile
|
86
|
-
[IiifS3::LEVEL_0,{
|
87
|
-
supports: ["cors","sizeByWhListed", "baseUriRedirect"]
|
88
|
-
}]
|
89
|
-
end
|
90
|
-
|
91
|
-
# TODO: Implement this. See <http://iiif.io/api/annex/services/#physical-dimensions>
|
92
|
-
def service
|
93
|
-
return nil
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|