wax_iiif 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/wax_iiif.svg)](https://badge.fury.io/rb/wax_iiif) [![Build Status](https://travis-ci.org/mnyrop/wax_iiif.svg?branch=master)](https://travis-ci.org/mnyrop/wax_iiif) [![Maintainability](https://api.codeclimate.com/v1/badges/3eb2fcf5ae47e7b6d686/maintainability)](https://codeclimate.com/github/mnyrop/wax_iiif/maintainability)
|
3
3
|
|
4
|
-
|
4
|
+
![License](https://img.shields.io/badge/license-MIT-green.svg) [![docs](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](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
|