class IiifS3::Builder
Constants
- HEADER_VAL
Attributes
@!attribute [r] config
@return [IiifS3::Config] The configuration object
@!attribute [r] data
@return [Array<Hash>] The raw data computed for the given set of images
@!attribute [r] manifests
@return [Array<Hash>] The manifest hashes for this configuration
Public Class Methods
Initialize the builder.
@param [Hash] config an optional configuration object. @see IiifS3::Config
@return [Void]
# File lib/iiif_s3/builder.rb, line 31 def initialize(config = {}) @manifests = [] @config = IiifS3::Config.new(config) end
Public Instance Methods
Creates the required directories for exporting to the file system.
@return [Void]
# File lib/iiif_s3/builder.rb, line 109 def create_build_directories root_dir = generate_build_location("") Dir.mkdir root_dir unless Dir.exists?(root_dir) img_dir = generate_image_location("","").split("/")[0...-1].join("/") Dir.mkdir img_dir unless Dir.exists?(img_dir) end
# File lib/iiif_s3/builder.rb, line 100 def generate_collection(label="top") collection = Collection.new(label,@config) manifests.each{|m| collection.add_manifest(m)} collection.save end
Load data into the IIIF builder.
This will load the data, perform some basic verifications on it, and sort it into proper order.
@param [Array<ImageRecord>, ImageRecord] data
Either a single ImageRecord or an Array of ImageRecords.
@raise [IiifS3::Error::InvalidImageData] if any of the data does
not pass the validation checks
@return [Void]
# File lib/iiif_s3/builder.rb, line 50 def load(data) @data = [data].flatten # handle hashes and arrays of hashes # validate @data.each do |image_record| raise IiifS3::Error::InvalidImageData, "Image record #{image_record.inspect} is not an ImageRecord" unless image_record.is_a? ImageRecord 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? end end
Load data into the IIIF server from a CSV
@param [String] csv_path Path to the CSV file containing the image data
@return [Void] @todo Fix this to use the correct data format!
# File lib/iiif_s3/builder.rb, line 123 def load_csv(csv_path) raise Error::InvalidCSV unless File.exist? csv_path begin vals = CSV.read(csv_path) rescue CSV::MalformedCSVError raise Error::InvalidCSV end raise Error::BlankCSV if vals.length == 0 raise Error::InvalidCSV if vals[0].length != 3 # remove optional header vals.shift if vals[0][0] == HEADER_VAL @data = vals.collect do |data| { "image_path" => data[0], "id" => data[1], "label" => data[2] } end end
Take the loaded data and generate all the files.
@param [Boolean] force_image_generation Generate images even if they already exist
@return [Void]
# File lib/iiif_s3/builder.rb, line 68 def process_data(force_image_generation=false) return nil if @data.nil? # do nothing without data. @manifests = [] resources = {} @data.each do |image_record| # image generation # # It attempts to load the info files and skip generation — not currently working. info_file = image_info_file_name(image_record) if (File.exist?(info_file) && !force_image_generation) puts "skipping #{info_file}" if @config.verbose? image_record.variants = load_variants(info_file) else image_record.variants = generate_variants(image_record, @config) generate_tiles(image_record, @config) generate_image_json(image_record, @config) end # Save the image info for the manifest resources[image_record.id] ||= [] resources[image_record.id].push image_record end # Generate the manifests resources.each do |key, val| manifests.push generate_manifest(val, @config) end generate_collection end
Protected Instance Methods
# File lib/iiif_s3/builder.rb, line 228 def build_a_manifest manifest_uri = "@config.s3.bucket/#{generate_id(record)}/manifest.json" # response = Typhoeus.get(manifest_uri, followlocation: true) # if response.code == 200 # puts "Skipping #{file}—Manifest already exists." if verbose # data = JSON.parse(response.body) # obj = IiifS3::FakeManifest.new(data["@id"], data["@type"], data["label"]) # @iiif.manifests.push(obj) # next # end end
# File lib/iiif_s3/builder.rb, line 205 def generate_image_json(data, config) filename = image_info_file_name(data) info = ImageInfo.new(data.variants["full"].id, data.variants ,config.tile_width, config.tile_scale_factors) puts "writing #{filename}" if config.verbose? Pathname.new(Pathname.new(filename).dirname).mkpath File.open(filename, "w") do |file| file.puts info.to_json end if @config.upload_to_s3 add_file_to_s3(filename) add_default_redirect(filename) end return info end
# File lib/iiif_s3/builder.rb, line 222 def generate_manifest(data, config) m = Manifest.new(data, config) m.save_all_files_to_disk return m end
# File lib/iiif_s3/builder.rb, line 165 def generate_tiles(data, config) width = data.variants["full"].width tile_width = config.tile_width height = data.variants["full"].height tiles = [] config.tile_scale_factors.each do |s| (0..(height*1.0/(tile_width*s)).floor).each do |tileY| (0..(width*1.0/(tile_width*s)).floor).each do |tileX| tile = { scale_factor: s, xpos: tileX, ypos: tileY, x: tileX * tile_width * s, y: tileY * tile_width * s, width: tile_width * s, height: tile_width * s, xSize: tile_width, ySize: tile_width } if (tile[:x] + tile[:width] > width) tile[:width] = width - tile[:x] tile[:xSize] = (tile[:width]/(s*1.0)).ceil end if (tile[:y] + tile[:height] > height) tile[:height] = height - tile[:y] tile[:ySize] = (tile[:height]/(s*1.0)).ceil end tiles.push(tile) end end end tiles.each do |tile| ImageTile.new(data, @config, tile) end end
# File lib/iiif_s3/builder.rb, line 242 def generate_variants(data, config) obj = { "full" => FullImage.new(data, config), "thumbnail" => Thumbnail.new(data, config) } config.variants.each do |key,image_size| obj[key] = ImageVariant.new(data, config, image_size, image_size) end return obj end
# File lib/iiif_s3/builder.rb, line 201 def image_info_file_name(data) "#{generate_image_location(data.id,data.page_number)}/info.json" end
# File lib/iiif_s3/builder.rb, line 149 def load_variants(path) data = JSON.parse File.read(path) id = data["@id"] w = data["width"] h = data["height"] thumb_size = data["sizes"].find{|a| a["width"] == config.thumbnail_size || a["height"] == config.thumbnail_size} thumb_w = thumb_size["width"] thumb_h = thumb_size["height"] full_url = "#{id}/full/full/0/default.jpg" thumb_url = "#{id}/full/#{thumb_w},/0/default.jpg" full = FakeImageVariant.new( id,w, h,full_url, "image/jpeg") thumbnail = FakeImageVariant.new( id, thumb_w, thumb_h, thumb_url, "image/jpeg") return {"full" => full, "thumbnail" => thumbnail} end