class ImageOptim::Worker

Base class for all workers

Public Class Methods

new(image_optim, options = {}) click to toggle source

Configure (raises on extra options)

# File lib/image_optim/worker.rb, line 24
def initialize(image_optim, options = {})
  unless image_optim.is_a?(ImageOptim)
    fail ArgumentError, 'first parameter should be an ImageOptim instance'
  end

  @image_optim = image_optim
  parse_options(options)
  assert_no_unknown_options!(options)
end

Public Instance Methods

image_formats() click to toggle source

List of formats which worker can optimize

# File lib/image_optim/worker.rb, line 50
def image_formats
  format_from_name = self.class.name.downcase[/gif|jpeg|png|svg/]
  unless format_from_name
    fail "#{self.class}: can't guess applicable format from worker name"
  end

  [format_from_name.to_sym]
end
inspect() click to toggle source

Short inspect

# File lib/image_optim/worker.rb, line 86
def inspect
  options_string = self.class.option_definitions.map do |option|
    " @#{option.name}=#{send(option.name).inspect}"
  end.join(',')
  "#<#{self.class}#{options_string}>"
end
optimize(_src, _dst, options = {}) click to toggle source

Optimize image at src, output at dst, must be overriden in subclass return true on success

# File lib/image_optim/worker.rb, line 45
def optimize(_src, _dst, options = {})
  fail NotImplementedError, "implement method optimize in #{self.class}"
end
optimized?(src, dst) click to toggle source

Check if operation resulted in optimized file

# File lib/image_optim/worker.rb, line 80
def optimized?(src, dst)
  dst_size = dst.size?
  dst_size && dst_size < src.size
end
options() click to toggle source

Return hash with worker options

# File lib/image_optim/worker.rb, line 35
def options
  hash = {}
  self.class.option_definitions.each do |option|
    hash[option.name] = send(option.name)
  end
  hash
end
resolve_used_bins!() click to toggle source

Resolve used bins, raise exception concatenating all messages

# File lib/image_optim/worker.rb, line 70
def resolve_used_bins!
  errors = BinResolver.collect_errors(used_bins) do |bin|
    @image_optim.resolve_bin!(bin)
  end
  return if errors.empty?

  fail BinResolver::Error, wrap_resolver_error_message(errors.join(', '))
end
run_order() click to toggle source

Ordering in list of workers, 0 by default

# File lib/image_optim/worker.rb, line 60
def run_order
  0
end
used_bins() click to toggle source

List of bins used by worker

# File lib/image_optim/worker.rb, line 65
def used_bins
  [self.class.bin_sym]
end

Private Instance Methods

assert_no_unknown_options!(options) click to toggle source
# File lib/image_optim/worker.rb, line 102
def assert_no_unknown_options!(options)
  known_keys = self.class.option_definitions.map(&:name)
  unknown_options = options.reject{ |key, _value| known_keys.include?(key) }
  return if unknown_options.empty?

  fail ConfigurationError, "unknown options #{unknown_options.inspect} "\
                           "for #{self}"
end
execute(bin, arguments, options) click to toggle source

Run command setting priority and hiding output

# File lib/image_optim/worker.rb, line 126
def execute(bin, arguments, options)
  resolve_bin!(bin)

  cmd_args = [bin, *arguments].map(&:to_s)

  if @image_optim.verbose
    run_command_verbose(cmd_args, options)
  else
    run_command(cmd_args, options)
  end
end
parse_options(options) click to toggle source
# File lib/image_optim/worker.rb, line 95
def parse_options(options)
  self.class.option_definitions.each do |option_definition|
    value = option_definition.value(self, options)
    instance_variable_set("@#{option_definition.name}", value)
  end
end
resolve_bin!(bin) click to toggle source

Forward bin resolving to image_optim

# File lib/image_optim/worker.rb, line 112
def resolve_bin!(bin)
  @image_optim.resolve_bin!(bin)
rescue BinResolver::Error => e
  raise e, wrap_resolver_error_message(e.message), e.backtrace
end
run_command(cmd_args, options) click to toggle source

Run command defining environment, setting nice level, removing output and reraising signal exception

# File lib/image_optim/worker.rb, line 140
def run_command(cmd_args, options)
  args = [
    {'PATH' => @image_optim.env_path},
    *%W[nice -n #{@image_optim.nice}],
    *cmd_args,
    options.merge(out: Path::NULL, err: Path::NULL),
  ]
  Cmd.run(*args)
end
run_command_verbose(cmd_args, options) click to toggle source

Wrap run_command and output status, elapsed time and command

# File lib/image_optim/worker.rb, line 151
def run_command_verbose(cmd_args, options)
  start = ElapsedTime.now

  begin
    success = run_command(cmd_args, options)
    status = success ? '✓' : '✗'
    success
  rescue Errors::TimeoutExceeded
    status = 'timeout'
    raise
  ensure
    $stderr << format("%s %.1fs %s\n", status, ElapsedTime.now - start, cmd_args.shelljoin)
  end
end
wrap_resolver_error_message(message) click to toggle source
# File lib/image_optim/worker.rb, line 118
def wrap_resolver_error_message(message)
  name = self.class.bin_sym
  "#{name} worker: #{message}; please provide proper binary or "\
    "disable this worker (--no-#{name} argument or "\
    "`:#{name} => false` through options)"
end