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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8e8bfe689315b674d1af11bb292df7b42c6da7dcdaa4fe277b746ab2fcacc5c
|
4
|
+
data.tar.gz: 787041b5e001e26094254a123bf1d42327e1a2ec1d4c7af729f4b1aabb432318
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bed76dcd0835a29fcbf74eb01c38c4980d91af269eabde4d5f6535c058a2e81e4e7a2252a6b2d24c7c9029d142baf8600d6179ae3db2de95622682ea5a6acfe
|
7
|
+
data.tar.gz: 15683183c49c2968751abb425cc0d75a4b42d7d21ef7d11a0725b4cddc991079324bf3cf69d4ea9e330a81faf0b05303bd7c92ae827bd5a766eff7683b90d38d
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.4
|
3
|
+
Exclude: ['spec/**/*']
|
4
|
+
Metrics/LineLength:
|
5
|
+
IgnoredPatterns: ['raise', 'puts', '#', '@', 'spec']
|
6
|
+
Style/FrozenStringLiteralComment:
|
7
|
+
Enabled: false
|
8
|
+
Style/RedundantSelf:
|
9
|
+
Enabled: false
|
10
|
+
Metrics/MethodLength:
|
11
|
+
Enabled: false
|
12
|
+
Style/DoubleNegation:
|
13
|
+
Enabled: false
|
14
|
+
Metrics/AbcSize:
|
15
|
+
Enabled: false
|
16
|
+
Metrics/CyclomaticComplexity:
|
17
|
+
Enabled: false
|
18
|
+
Metrics/PerceivedComplexity:
|
19
|
+
Enabled: false
|
20
|
+
Metrics/ClassLength:
|
21
|
+
Enabled: false
|
22
|
+
Layout/EmptyLineAfterGuardClause:
|
23
|
+
Enabled: false
|
24
|
+
Lint/UriEscapeUnescape:
|
25
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# wax_iiif
|
2
|
-
[](https://badge.fury.io/rb/wax_iiif) [](https://travis-ci.org/mnyrop/wax_iiif) [](https://codeclimate.com/github/mnyrop/wax_iiif/maintainability)
|
3
3
|
|
4
|
-
|
4
|
+
 [](https://www.rubydoc.info/github/minicomp/wax_iiif/)
|
5
5
|
|
6
|
-
|
6
|
+
This fork is *mostly* a copy of the [iiif_s3 gem](https://github.com/cmoa/iiif_s3) with all the s3 dependencies and functionality removed. It creates level 0 IIIF derivatives for static exhibition sites with [Minicomp/Wax](https://minicomp.github.io/wax/) via [Wax_Tasks](https://minicomp.github.io/wax_tasks/).
|
7
7
|
|
8
|
-
|
8
|
+
Documentation for using `wax_iiif` without `wax_tasks` is forthcoming. In the meantime, check out [rubydoc](https://www.rubydoc.info/gems/wax_iiif).
|
data/lib/wax_iiif.rb
CHANGED
@@ -1,83 +1,73 @@
|
|
1
1
|
require 'csv'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
require "iiif_s3/utilities"
|
4
|
+
require_relative 'wax_iiif/errors'
|
5
|
+
require_relative 'wax_iiif/base_properties'
|
6
|
+
require_relative 'wax_iiif/image_record'
|
7
|
+
require_relative 'wax_iiif/builder'
|
8
|
+
require_relative 'wax_iiif/manifest'
|
9
|
+
require_relative 'wax_iiif/config'
|
10
|
+
require_relative 'wax_iiif/collection'
|
11
|
+
require_relative 'wax_iiif/image_variant'
|
12
|
+
require_relative 'wax_iiif/thumbnail'
|
13
|
+
require_relative 'wax_iiif/image_tile'
|
14
|
+
require_relative 'wax_iiif/full_image'
|
15
|
+
require_relative 'wax_iiif/image_info'
|
16
|
+
require_relative 'wax_iiif/utilities'
|
18
17
|
|
19
|
-
# Module
|
18
|
+
# Module WaxIiif is a tool for generating IIIF resources from a set of files.
|
20
19
|
# It's designed to support the IIIF level 0 profile, and generates entirely static files.
|
21
20
|
#
|
22
21
|
# @author David Newbury <david.newbury@gmail.com>
|
23
22
|
#
|
24
|
-
module
|
25
|
-
|
26
|
-
|
23
|
+
module WaxIiif
|
27
24
|
#--------------------------------------------------------------------------
|
28
25
|
# CONSTANTS
|
29
26
|
#--------------------------------------------------------------------------
|
30
27
|
|
31
|
-
|
32
28
|
# @return [String] The URI of the presentation context for the IIIF V.2
|
33
|
-
PRESENTATION_CONTEXT =
|
29
|
+
PRESENTATION_CONTEXT = 'http://iiif.io/api/presentation/2/context.json'.freeze
|
34
30
|
# @return [String] The URI of the image context for the IIIF V.2
|
35
|
-
IMAGE_CONTEXT =
|
31
|
+
IMAGE_CONTEXT = 'http://iiif.io/api/image/2/context.json'.freeze
|
36
32
|
# @return [String] The URI of the image protocol for IIIF
|
37
|
-
IMAGE_PROTOCOL =
|
33
|
+
IMAGE_PROTOCOL = 'http://iiif.io/api/image'.freeze
|
38
34
|
# @return [String] The URI of the Level 0 profile for the IIIF V.2
|
39
|
-
LEVEL_0 =
|
35
|
+
LEVEL_0 = 'http://iiif.io/api/image/2/level0.json'.freeze
|
40
36
|
# @return [String] The IIIF default type for a sequence.
|
41
|
-
SEQUENCE_TYPE =
|
37
|
+
SEQUENCE_TYPE = 'sc:Sequence'.freeze
|
42
38
|
# @return [String] The IIIF default type for a canvas
|
43
|
-
CANVAS_TYPE =
|
39
|
+
CANVAS_TYPE = 'sc:Canvas'.freeze
|
44
40
|
# @return [String] The IIIF default type for a annotation.
|
45
|
-
ANNOTATION_TYPE =
|
41
|
+
ANNOTATION_TYPE = 'oa:Annotation'.freeze
|
46
42
|
# @return [String] The IIIF default type for an image.
|
47
|
-
IMAGE_TYPE =
|
43
|
+
IMAGE_TYPE = 'dcterms:Image'.freeze
|
48
44
|
# @return [String] The default label for a canvas without a specified name.
|
49
|
-
MOTIVATION =
|
45
|
+
MOTIVATION = 'sc:painting'.freeze
|
50
46
|
# @return [String] The default label for a canvas without a specified name.
|
51
|
-
DEFAULT_CANVAS_LABEL =
|
47
|
+
DEFAULT_CANVAS_LABEL = 'front'.freeze
|
52
48
|
# @return [String] The default name for a sequence without a specified name.
|
53
|
-
DEFAULT_SEQUENCE_NAME =
|
49
|
+
DEFAULT_SEQUENCE_NAME = 'default'.freeze
|
54
50
|
# @return [String] The default reading direction for this manifest.
|
55
|
-
DEFAULT_VIEWING_DIRECTION =
|
51
|
+
DEFAULT_VIEWING_DIRECTION = 'left-to-right'.freeze
|
56
52
|
# @return [Number] The size in pixels below which the canvas will be doubled.
|
57
53
|
MIN_CANVAS_SIZE = 1200
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
#--------------------------------------------------------------------------
|
63
|
-
|
64
|
-
|
55
|
+
#--------------------------------------------------------------------------
|
56
|
+
# HELPERS
|
57
|
+
#--------------------------------------------------------------------------
|
65
58
|
|
66
59
|
# Validates a viewing direction string against the IIIF V.2.0 spec.
|
67
60
|
#
|
68
61
|
# According to v2 of the IIIF standards, there are only four valid viewing directions:
|
69
|
-
#
|
62
|
+
# 'left-to-right', 'top-to-bottom', 'bottom-to-top' , and 'right-to-left'. This
|
70
63
|
# returns true if the provided direction is one of these, and falst for anything else.
|
71
64
|
#
|
72
65
|
# @param [String] direction A viewing direction string
|
73
66
|
#
|
74
67
|
# @return [boolean] Is the provided string a valid viewing direction?
|
75
68
|
#
|
76
|
-
def self.
|
77
|
-
|
78
|
-
direction
|
79
|
-
direction == "bottom-to-top" ||
|
80
|
-
direction == "right-to-left"
|
69
|
+
def self.valid_viewing_direction?(direction)
|
70
|
+
valid = %w[left-to-right top-to-bottom bottom-to-top right-to-left]
|
71
|
+
valid.include? direction
|
81
72
|
end
|
82
|
-
|
83
73
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative 'utilities'
|
2
|
+
module WaxIiif
|
3
|
+
# Module BaseProperties provides the set of properties that are
|
4
|
+
# shared across all IIIF types.
|
5
|
+
#
|
6
|
+
# It is not a comprehensive list (yet), but it does handle
|
7
|
+
# most of the shared types. It does not include any types
|
8
|
+
# that have class-based restrictions.
|
9
|
+
#
|
10
|
+
# It also performs some basic sanity checking on (some of) the
|
11
|
+
# fields, and provides utility classes that are applicable across
|
12
|
+
# the fields.
|
13
|
+
#
|
14
|
+
# @todo Add within, service, seeAlso, viewingHint fields
|
15
|
+
# @author David Newbury <david.newbury@gmail.com>
|
16
|
+
#
|
17
|
+
module BaseProperties
|
18
|
+
include Utilities::Helpers
|
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=(the_id)
|
58
|
+
@id = generate_id(the_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
|
84
|
+
#
|
85
|
+
# @return [Void]
|
86
|
+
def save
|
87
|
+
save_to_disk(JSON.parse(self.to_json))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require_relative 'utilities'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module WaxIiif
|
5
|
+
# Builder class
|
6
|
+
class Builder
|
7
|
+
include Utilities::Helpers
|
8
|
+
|
9
|
+
HEADER_VAL = 'filename'.freeze
|
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 [WaxIiif::Config] The configuration object
|
23
|
+
attr_reader :config
|
24
|
+
|
25
|
+
# Initialize the builder.
|
26
|
+
#
|
27
|
+
# @param [Hash] config an optional configuration object.
|
28
|
+
# @see WaxIiif::Config
|
29
|
+
# @return [Void]
|
30
|
+
#
|
31
|
+
def initialize(config = {})
|
32
|
+
@manifests = []
|
33
|
+
@config = WaxIiif::Config.new(config)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Load data into the IIIF builder.
|
38
|
+
#
|
39
|
+
# This will load the data, perform some basic verifications on it, and sort
|
40
|
+
# it into proper order.
|
41
|
+
#
|
42
|
+
# @param [Array<ImageRecord>, ImageRecord] data
|
43
|
+
# Either a single ImageRecord or an Array of ImageRecords.
|
44
|
+
# @raise [WaxIiif::Error::InvalidImageData] if any of the data does
|
45
|
+
# not pass the validation checks
|
46
|
+
#
|
47
|
+
# @return [Void]
|
48
|
+
#
|
49
|
+
def load(data)
|
50
|
+
@data = [data].flatten # handle hashes and arrays of hashes
|
51
|
+
# validate
|
52
|
+
@data.each do |image_record|
|
53
|
+
raise WaxIiif::Error::InvalidImageData, "Image record #{image_record.inspect} is not an ImageRecord" unless image_record.is_a? ImageRecord
|
54
|
+
raise WaxIiif::Error::InvalidImageData, "Image record #{image_record.inspect} does not have an ID" if image_record.id.nil?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Take the loaded data and generate all the files.
|
60
|
+
#
|
61
|
+
# @param [Boolean] force_image_generation Generate images even if they already exist
|
62
|
+
#
|
63
|
+
# @return [Void]
|
64
|
+
#
|
65
|
+
def process_data(force_image_generation = false)
|
66
|
+
return nil if @data.nil? # do nothing without data.
|
67
|
+
|
68
|
+
@manifests = []
|
69
|
+
@data.group_by(&:manifest_id).each do |key, value|
|
70
|
+
resources = {}
|
71
|
+
manifest_id = key
|
72
|
+
image_records = value
|
73
|
+
|
74
|
+
# genrate the images
|
75
|
+
image_records.each do |image_record|
|
76
|
+
# It attempts to load the info files and skip generation - not currently working.
|
77
|
+
info_file = image_info_file_name(image_record)
|
78
|
+
if File.exist?(info_file) && !force_image_generation
|
79
|
+
puts "skipping #{info_file}" if @config.verbose?
|
80
|
+
image_record.variants = load_variants(info_file)
|
81
|
+
else
|
82
|
+
image_record.variants = generate_variants(image_record, @config)
|
83
|
+
generate_tiles(image_record, @config)
|
84
|
+
generate_image_json(image_record, @config)
|
85
|
+
end
|
86
|
+
# Save the image info for the manifest
|
87
|
+
resources[image_record.id] ||= []
|
88
|
+
resources[image_record.id].push image_record
|
89
|
+
end
|
90
|
+
|
91
|
+
# Generate the manifest
|
92
|
+
if manifest_id.to_s.empty?
|
93
|
+
resources.each do |_key, val|
|
94
|
+
manifests.push generate_manifest(val, @config)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
manifests.push generate_manifest(image_records, @config)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
generate_collection
|
102
|
+
end
|
103
|
+
|
104
|
+
def generate_collection
|
105
|
+
collection = Collection.new(@config)
|
106
|
+
manifests.each { |m| collection.add_manifest(m) }
|
107
|
+
collection.save
|
108
|
+
end
|
109
|
+
|
110
|
+
# Creates the required directories for exporting to the file system.
|
111
|
+
#
|
112
|
+
# @return [Void]
|
113
|
+
def create_build_directories
|
114
|
+
root_dir = generate_build_location('')
|
115
|
+
Dir.mkdir root_dir unless Dir.exist?(root_dir)
|
116
|
+
img_dir = generate_image_location('').split('/')[0...-1].join('/')
|
117
|
+
Dir.mkdir img_dir unless Dir.exist?(img_dir)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Load data into the IIIF server from a CSV
|
121
|
+
#
|
122
|
+
# @param [String] csv_path Path to the CSV file containing the image data
|
123
|
+
#
|
124
|
+
# @return [Void]
|
125
|
+
# @todo Fix this to use the correct data format!
|
126
|
+
#
|
127
|
+
def load_csv(csv_path)
|
128
|
+
raise Error::InvalidCSV unless File.exist? csv_path
|
129
|
+
begin
|
130
|
+
vals = CSV.read(csv_path)
|
131
|
+
rescue CSV::MalformedCSVError
|
132
|
+
raise Error::InvalidCSV
|
133
|
+
end
|
134
|
+
|
135
|
+
raise Error::BlankCSV if vals.length.zero?
|
136
|
+
raise Error::InvalidCSV if vals[0].length != 3
|
137
|
+
|
138
|
+
# remove optional header
|
139
|
+
vals.shift if vals[0][0] == HEADER_VAL
|
140
|
+
|
141
|
+
@data = vals.collect do |data|
|
142
|
+
{
|
143
|
+
'image_path' => data[0],
|
144
|
+
'id' => data[1],
|
145
|
+
'label' => data[2]
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
151
|
+
|
152
|
+
#----------------------------------------------------------------
|
153
|
+
def load_variants(path)
|
154
|
+
data = JSON.parse escape_yaml(File.read(path))
|
155
|
+
id = data['@id']
|
156
|
+
w = data['width']
|
157
|
+
h = data['height']
|
158
|
+
|
159
|
+
thumb_size = data['sizes'].find do |a|
|
160
|
+
same_width = a['width'] == config.thumbnail_size
|
161
|
+
same_height = a['height'] == config.thumbnail_size
|
162
|
+
same_width || same_height
|
163
|
+
end
|
164
|
+
|
165
|
+
thumb_w = thumb_size['width']
|
166
|
+
thumb_h = thumb_size['height']
|
167
|
+
full_url = "#{id}/full/full/0/default.jpg"
|
168
|
+
thumb_url = "#{id}/full/#{thumb_w},/0/default.jpg"
|
169
|
+
full = FakeImageVariant.new(id,
|
170
|
+
w,
|
171
|
+
h,
|
172
|
+
full_url,
|
173
|
+
'image/jpeg')
|
174
|
+
thumbnail = FakeImageVariant.new(id,
|
175
|
+
thumb_w,
|
176
|
+
thumb_h,
|
177
|
+
thumb_url,
|
178
|
+
'image/jpeg')
|
179
|
+
|
180
|
+
{ 'full' => full, 'thumbnail' => thumbnail }
|
181
|
+
end
|
182
|
+
|
183
|
+
def generate_tiles(data, config)
|
184
|
+
width = data.variants['full'].width
|
185
|
+
tile_width = config.tile_width
|
186
|
+
height = data.variants['full'].height
|
187
|
+
tiles = []
|
188
|
+
config.tile_scale_factors.each do |s|
|
189
|
+
(0..(height * 1.0 / (tile_width * s)).floor).each do |tile_y|
|
190
|
+
(0..(width * 1.0 / (tile_width * s)).floor).each do |tile_x|
|
191
|
+
tile = {
|
192
|
+
scale_factor: s,
|
193
|
+
xpos: tile_x,
|
194
|
+
ypos: tile_y,
|
195
|
+
x: tile_x * tile_width * s,
|
196
|
+
y: tile_y * tile_width * s,
|
197
|
+
width: tile_width * s,
|
198
|
+
height: tile_width * s,
|
199
|
+
xSize: tile_width,
|
200
|
+
ySize: tile_width
|
201
|
+
}
|
202
|
+
if tile[:x] + tile[:width] > width
|
203
|
+
tile[:width] = width - tile[:x]
|
204
|
+
tile[:xSize] = (tile[:width] / (s * 1.0)).ceil
|
205
|
+
end
|
206
|
+
if tile[:y] + tile[:height] > height
|
207
|
+
tile[:height] = height - tile[:y]
|
208
|
+
tile[:ySize] = (tile[:height] / (s * 1.0)).ceil
|
209
|
+
end
|
210
|
+
tiles.push(tile)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
tiles.each do |tile|
|
215
|
+
ImageTile.new(data, @config, tile)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def image_info_file_name(data)
|
220
|
+
"#{generate_image_location(data.id)}/info.json"
|
221
|
+
end
|
222
|
+
|
223
|
+
def generate_image_json(data, config)
|
224
|
+
filename = image_info_file_name(data)
|
225
|
+
info = ImageInfo.new(data.variants['full'].id,
|
226
|
+
data.variants,
|
227
|
+
config.tile_width,
|
228
|
+
config.tile_scale_factors)
|
229
|
+
puts "writing #{filename}" if config.verbose?
|
230
|
+
Pathname.new(Pathname.new(filename).dirname).mkpath
|
231
|
+
File.open(filename, 'w') { |file| file.puts info.to_json }
|
232
|
+
info
|
233
|
+
end
|
234
|
+
|
235
|
+
def generate_manifest(data, config)
|
236
|
+
m = Manifest.new(data, config)
|
237
|
+
m.save_all_files_to_disk
|
238
|
+
m
|
239
|
+
end
|
240
|
+
|
241
|
+
def generate_variants(data, config)
|
242
|
+
obj = {
|
243
|
+
'full' => FullImage.new(data, config),
|
244
|
+
'thumbnail' => Thumbnail.new(data, config)
|
245
|
+
}
|
246
|
+
config.variants.each do |key, image_size|
|
247
|
+
obj[key] = ImageVariant.new(data, config, image_size)
|
248
|
+
end
|
249
|
+
obj
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|