111 lines
2.7 KiB
Ruby
111 lines
2.7 KiB
Ruby
class RulesEvaluator
|
|
|
|
def evaluate(email, rule_set_or_sets)
|
|
if rule_set_or_sets.respond_to? :each
|
|
rule_set_or_sets.each do |rule_set|
|
|
email = evaluate_rule_set(email, rule_set)
|
|
end
|
|
else
|
|
email = evaluate_rule_set(email, rule_set_or_sets)
|
|
end
|
|
|
|
email
|
|
end
|
|
|
|
private
|
|
|
|
def evaluate_rule_set(email, rule_set)
|
|
rules_state = true
|
|
|
|
rule_set.rules.enabled.each do |rule|
|
|
subjects = prepare_subjects(email, rule)
|
|
result = apply_rule(subjects, rule)
|
|
result = ! result if rule.inverted?
|
|
rules_state = apply_operator(rules_state, rule_set.operator, result)
|
|
|
|
break unless rules_state
|
|
end
|
|
|
|
if rules_state
|
|
rule_set.actions.enabled.each do |action|
|
|
klass = action.class_name.constantize
|
|
email = klass.new.process(email)
|
|
# rescue NameError => ex
|
|
# # TODO: log a warning
|
|
end
|
|
end
|
|
|
|
email
|
|
end
|
|
|
|
def prepare_subjects(email, rule)
|
|
case rule.subject_type.downcase
|
|
when "header"
|
|
Array(email.header_values(rule.subject_value))
|
|
when "body"
|
|
Array(email.plain_body)
|
|
else
|
|
raise ArgumentError, "Unrecognized subject type '#{rule.subject_type}'"
|
|
end
|
|
end
|
|
|
|
def apply_rule(subjects, rule)
|
|
case rule.condition_type.downcase
|
|
when "match", "matches"
|
|
subjects.any? { |subject|
|
|
pattern = Regexp.new(rule.condition_value)
|
|
subject.match?
|
|
}
|
|
when "equal", "equals"
|
|
subjects.any? { |subject|
|
|
subject == rule.condition_value
|
|
}
|
|
when "start", "starts"
|
|
subjects.any? { |subject|
|
|
subject.starts_with? rule.condition_value
|
|
}
|
|
when "end", "ends"
|
|
subjects.any? { |subject|
|
|
subject.ends_with? rule.condition_value
|
|
}
|
|
when "contain", "contains"
|
|
subjects.any? { |subject|
|
|
subject.include? rule.condition_value
|
|
}
|
|
when "exist", "exists"
|
|
subjects.any? { |subject|
|
|
subject.exists?
|
|
}
|
|
when "empty"
|
|
subjects.all? { |subject|
|
|
subject.empty?
|
|
}
|
|
when "date_before"
|
|
# subjects.all? { |subject|
|
|
# subject.empty?
|
|
# }
|
|
when "date_after"
|
|
# subjects.all? { |subject|
|
|
# subject.empty?
|
|
# }
|
|
else
|
|
raise ArgumentError, "Unrecognized condition type '#{rule. condition_type}'"
|
|
end
|
|
|
|
def apply_operator(state, operator, result)
|
|
case operator.upcase
|
|
when "AND"
|
|
(state and result)
|
|
when "OR"
|
|
(state or result)
|
|
when "XOR"
|
|
(state or result) and !(rules_state and result)
|
|
else
|
|
raise ArgumentError, "Unrecognized operator '#{operator}'"
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
end
|