lib/photish/render/image.rb
module Photish
module Render
class Image
include Log::Loggable
def initialize(config, version_hash)
@config = config
@version_hash = version_hash
end
def render(images)
log.debug "Rendering #{images.count} images across #{threads} threads"
setup_minimagick
cache_load_from_disk
threads = spawn_thread_instances(to_queue(images))
threads.map(&:join)
cache_flush_to_disk
end
private
attr_reader :config,
:version_hash
delegate :output_dir,
:worker_index,
:threads,
:soft_failure,
:workers,
to: :config
delegate :record,
:changed?,
:flush_to_disk,
:load_from_disk,
to: :cache,
prefix: true
def spawn_thread_instances(image_queue)
(0...threads).map do
Thread.new do
process_images(image_queue)
end
end
end
def process_images(image_queue)
while !image_queue.empty?
process_next_image(image_queue)
end
end
def process_next_image(image_queue)
image = image_queue.pop
convert(image) if regenerate?(image)
rescue Errno::ENOENT
log.warn "Image not found #{image.path}"
raise unless soft_failure
end
def regenerate?(image)
cache_changed?(image.url_path, image.path) ||
!File.exist?(output_path(image))
end
def to_queue(images)
image_queue = Queue.new
Array(images).shuffle.each { |image| image_queue << image }
image_queue
end
def convert(image)
create_parent_directories(image)
convert_with_imagemagick(image)
cache_record(image.url_path, image.path)
end
def convert_with_imagemagick(image)
MiniMagick::Tool::Convert.new do |convert|
convert << image.path
convert.merge!(image.quality_params)
convert << output_path(image)
end
rescue MiniMagick::Error => e
log.warn "Error occured while converting"
log.warn e
raise unless soft_failure
end
def output_path(image)
File.join(output_dir, image.url_parts)
end
def create_parent_directories(image)
FileUtils.mkdir_p(File.join(output_dir, image.base_url_parts))
end
def cache
@cache ||= Cache::Manifest.new(output_dir,
workers,
worker_index,
version_hash)
end
def minimagick_config
config.dependencies.minimagick
end
def debug?
config.logging.level == 'debug'
end
def setup_minimagick
MiniMagick.configure do |config|
config.cli = minimagick_config.cli.to_sym
config.cli_path = minimagick_config.cli_path if minimagick_config.cli_path
config.timeout = minimagick_config.timeout
config.validate_on_create = minimagick_config.validate_on_create
config.validate_on_write = minimagick_config.validate_on_write
config.whiny = minimagick_config.whiny
end
MiniMagick.logger = log if debug?
end
end
end
end