class MovieMasher::FilterEvaluated

module filter

Attributes

parameters[R]

Public Class Methods

new(filter_config, mash_input = nil, applied_input = nil) click to toggle source
Calls superclass method MovieMasher::Filter.new
# File lib/graphs/filters.rb, line 57
def initialize(filter_config, mash_input = nil, applied_input = nil)
  # applied_input same as filter_config for themes
  @config = filter_config
  raise(Error::Parameter, 'no config') unless @config
  @parameters = @config[:parameters]
  @evaluated = {}
  @mash_input = mash_input
  @applied_input = applied_input
  unless @parameters
    sym = filter_config[:id].upcase.to_sym
    if Parameters.const_defined?(sym)
      @parameters = Parameters.const_get(sym)
    end
    @parameters ||= []
  end
  super @config[:id]
end

Public Instance Methods

__command_name_value(name, value, scope) click to toggle source
# File lib/graphs/filters.rb, line 74
def __command_name_value(name, value, scope)
  __raise_unless(value, '__command_name_value got nil value')
  result = value
  if value.is_a?(Array)
    result = nil
    bind = __filter_scope_binding(scope)
    condition_is_true = false
    value.each do |conditional|
      condition = conditional[:condition]
      if conditional[:is]
        condition += '==' + conditional[:is].to_s
      elsif conditional[:in]
        unless conditional[:in].is_a?(Array)
          conditional[:in] = conditional[:in].split(',')
        end
        condition = "include(#{condition}, #{conditional[:in].join(', ')})"
      end
      condition = "if ((#{condition}), 1, 0)"
      calculator = Dentaku::Calculator.new
      calculator.add_function(
        :include, :numeric, ->(n, *args) { args.include?(n) }
      )
      condition_is_true = !calculator.evaluate(condition, bind).zero?
      if condition_is_true
        result = __scope_value(scope, conditional[:value])
        break
      end
    end
    raise(Error::JobInput, 'zero true conditions') unless condition_is_true
  else
    result = __scope_value(scope, value)
  end
  result = Evaluate.equation(result)
  result = __coerce_if_numeric(result)
  name = ShellHelper.escape(name)
  result = ShellHelper.escape(result)
  @evaluated[name] = result
  "#{name}=#{result}"
end
__filter_dimension_keys(filter_id) click to toggle source
# File lib/graphs/filters.rb, line 119
def __filter_dimension_keys(filter_id)
  case filter_id
  when 'crop'
    { w: %w(w out_w), h: %w(h out_h) }
  when 'scale', 'pad'
    { w: %w(w width), h: %w(h height) }
  end
end
__filter_is_source?(filter_id) click to toggle source
# File lib/graphs/filters.rb, line 127
def __filter_is_source?(filter_id)
  %w(color movie).include?(filter_id)
end
__filter_scope_binding(scope) click to toggle source
# File lib/graphs/filters.rb, line 130
def __filter_scope_binding(scope)
  bind = {}
  scope.each { |k, v| bind[k.to_sym] = __coerce_if_numeric(v) } if scope
  bind
end
__is_filter_helper(func) click to toggle source
# File lib/graphs/filters.rb, line 113
def __is_filter_helper(func)
  func_sym = func.to_sym
  ok = FilterHelpers.respond_to?(func_sym)
  ok &&= func.start_with?('mm_') || %w(rgb rgba).include?(func)
  ok
end
__scope_value(scope, value_str) click to toggle source
# File lib/graphs/filters.rb, line 135
def __scope_value(scope, value_str)
  if scope
    # puts "1 value_str = #{value_str}"
    level = 0
    deepest = 0
    esc = '~'
    # expand variables
    value_str = value_str.to_s.dup
    value_str.gsub!(/([\w]+)/) do |match|
      match_str = match.to_s
      match_sym = match_str.to_sym
      if scope[match_sym]
        scope[match_sym].to_s
      else
        match_str
      end
    end
    # puts "2 value_str = #{value_str}"
    value_str.gsub!(/[()]/) do |paren|
      result = paren.to_s
      case result
      when '('
        level += 1
        deepest = [deepest, level].max
        result = "(#{level}#{esc}"
      when ')'
        result = ")#{level}#{esc}"
        level -= 1
      end
      result
    end
    # puts "3 value_str = #{value_str}"
    while 0 < deepest
      # puts "PRE #{deepest}: #{value_str}"
      reg_str = "([a-z_]+)[(]#{deepest}[#{esc}](.*?)[)]#{deepest}[#{esc}]"
      regexp = Regexp.new(reg_str)
      value_str = value_str.gsub(regexp) do
        Regexp.last_match.captures[0]
        method = Regexp.last_match.captures.first
        param_str = Regexp.last_match.captures.last
        params = param_str.split(',').map(&:strip)
        if __is_filter_helper(method)
          result = FilterHelpers.send(
            method.to_sym, params, @mash_input[:mash], scope
          )
          __raise_unless(result, "got false #{method}(#{params.join ','})")
          result = result.to_s
          __raise_if_empty(result, "empty #{method}(#{params.join(',')})")
        else
          result = "#{method}(#{params.join ','})"
        end
        result
      end
      # puts "POST METHODS #{deepest}: #{value_str}"
      # replace all simple equations in parentheses
      reg_str = "[(]#{deepest}[#{esc}](.*?)[)]#{deepest}[#{esc}]"
      value_str = value_str.gsub(Regexp.new(reg_str)) do
        evaluated = Evaluate.equation(Regexp.last_match[1])
        evaluated = "(#{evaluated})" unless evaluated.respond_to?(:round)
        evaluated.to_s
      end
      # puts "POST EQUATIONS #{deepest}: #{value_str}"
      deepest -= 1
    end
    # remove any lingering markers
    regexp = Regexp.new("([()])[0-9]+[#{esc}]")
    value_str = value_str.gsub(regexp) { Regexp.last_match[1] }
    # remove whitespace
    # value_str.gsub!(/\s/, '')
    # puts "4 value_str = #{value_str}"
  end
  Evaluate.equation(value_str)
end
command_parameters(scope) click to toggle source
# File lib/graphs/filters.rb, line 6
def command_parameters(scope)
  cmds = []
  if @parameters
    __raise_unless(@parameters.is_a?(Array), 'parameters is not an array')
    @parameters.each do |parameter|
      __raise_unless(parameter.is_a?(Hash), 'parameter is not a hash')
      name = parameter[:name]
      evaluated = parameter[:value]
      cmds << __command_name_value(name, evaluated, scope)
    end
  end
  cmds.join(':')
end
filter_command(scope = nil) click to toggle source
Calls superclass method MovieMasher::Filter#filter_command
# File lib/graphs/filters.rb, line 19
def filter_command(scope = nil)
  cmd = super
  return cmd if cmd.empty?
  @evaluated = {}
  cmds = []
  cmds << cmd
  if scope
    if Filter.__outsize['w'] && Filter.__outsize['h']
      scope[:mm_in_w] = Filter.__outsize['w']
      scope[:mm_in_h] = Filter.__outsize['h']
      # puts "<< #{scope[:mm_in_w]}x#{scope[:mm_in_h]} #{@id}"
    else
      scope[:mm_in_w] = 'in_w'
      scope[:mm_in_h] = 'in_h'
    end
  end
  cmd = command_parameters(scope)
  unless cmd.to_s.empty?
    cmds << '='
    cmds << cmd
  end
  cmd = cmds.join ''
  dimension_keys = __filter_dimension_keys @id
  if dimension_keys
    dimension_keys.each do |w_or_h, keys|
      keys.each do |key|
        next unless @evaluated[key]
        evaluated = @evaluated[key]
        if evaluated.respond_to?(:round)
          Filter.__outsize[w_or_h] = evaluated
        end
        break
      end
    end
  end
  @evaluated = {}
  cmd
end