rucaptcha/lib/rucaptcha/espeak.rb

88 lines
2.2 KiB
Ruby

module RuCaptcha
# espeak wrapper
class Espeak
require 'fileutils'
EspeakDataDir = "#{ENV['HOME']}/espeak-ng-data"
EspeakBuildDir = "#{ENV['HOME']}/.espeak_build"
EspeakLibDir = "#{ENV['HOME']}/shared_library"
unless Dir.exist?(EspeakDataDir)
FileUtils.cp_r(File.expand_path("../../../resources/espeak-ng-data", __FILE__), EspeakDataDir)
end
if Dir.exist?(EspeakBuildDir)
unless Dir.exist?(EspeakLibDir)
FileUtils.cp_r(File.expand_path("../../../resources/espeak_build/shared_library", __FILE__), EspeakLibDir)
end
else
FileUtils.cp_r(File.expand_path("../../../resources/espeak_build", __FILE__), EspeakBuildDir)
end
# generator for captcha images
def initialize(&block)
defaults
yield self if block_given?
end
# set default values
def defaults
@amplitude = 80..120
@pitch = 30..70
@gap = 80
@voice = nil
end
attr_writer :amplitude, :pitch, :gap, :voice
# return amplitude
def amplitude
if @amplitude.is_a? Range
@amplitude.to_a.sort_by { rand }.first
else
@amplitude.to_i
end
end
# return amplitude
def pitch
if @pitch.is_a? Range
@pitch.to_a.sort_by { rand }.first
else
@pitch.to_i
end
end
def gap
@gap.to_i
end
def voice
if @voice.is_a? Array
v = @voice.sort_by { rand }.first
else
v = @voice
end
v.try :gsub, /[^A-Za-z0-9\-\+]/, ""
end
# generate wav file by captcha
def generate(captcha, wav_file)
# get code
if captcha.is_a? String
code = captcha
else
raise ArgumentError, "invalid captcha"
end
# add spaces
code = code.each_char.to_a.join(" ")
cmd = "~/.espeak_build/espeak-ng -g 10"
cmd << " -a #{amplitude}" unless @amplitude.nil?
cmd << " -p #{pitch}" unless @pitch.nil?
cmd << " -g #{gap}" unless @gap.nil?
cmd << " -v '#{voice}'" unless @voice.nil?
cmd << " -w #{wav_file} ' #{code}'"
system({'LD_LIBRARY_PATH'=>"#{ENV['HOME']}/.espeak_build/shared_library"}, cmd)
true
end
end
end