easy_captcha 0.5.1 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -1
- data/Gemfile.lock +6 -7
- data/README.rdoc +22 -6
- data/easy_captcha.gemspec +0 -1
- data/lib/easy_captcha.rb +21 -1
- data/lib/easy_captcha/controller.rb +5 -1
- data/lib/easy_captcha/controller_helpers.rb +35 -3
- data/lib/easy_captcha/espeak.rb +79 -0
- data/lib/easy_captcha/version.rb +1 -1
- data/lib/easy_captcha/view_helpers.rb +1 -1
- data/lib/generators/templates/easy_captcha.rb +16 -1
- data/spec/espeak_spec.rb +24 -0
- metadata +4 -6
- data/lib/easy_captcha/parameters.rb +0 -31
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
easy_captcha (0.
|
4
|
+
easy_captcha (0.6.0)
|
5
5
|
bundler (>= 1.1.0)
|
6
6
|
rails (>= 3.0.0)
|
7
7
|
rmagick (>= 2.13.1)
|
@@ -88,15 +88,15 @@ GEM
|
|
88
88
|
rspec-expectations (2.11.3)
|
89
89
|
diff-lcs (~> 1.1.3)
|
90
90
|
rspec-mocks (2.11.3)
|
91
|
-
rspec-rails (2.11.
|
91
|
+
rspec-rails (2.11.4)
|
92
92
|
actionpack (>= 3.0)
|
93
93
|
activesupport (>= 3.0)
|
94
94
|
railties (>= 3.0)
|
95
95
|
rspec (~> 2.11.0)
|
96
|
-
simplecov (0.
|
96
|
+
simplecov (0.7.1)
|
97
97
|
multi_json (~> 1.0)
|
98
|
-
simplecov-html (~> 0.
|
99
|
-
simplecov-html (0.
|
98
|
+
simplecov-html (~> 0.7.1)
|
99
|
+
simplecov-html (0.7.1)
|
100
100
|
sprockets (2.1.3)
|
101
101
|
hike (~> 1.2)
|
102
102
|
rack (~> 1.0)
|
@@ -107,10 +107,9 @@ GEM
|
|
107
107
|
polyglot
|
108
108
|
polyglot (>= 0.3.1)
|
109
109
|
tzinfo (0.3.33)
|
110
|
-
yard (0.8.
|
110
|
+
yard (0.8.3)
|
111
111
|
|
112
112
|
PLATFORMS
|
113
|
-
java
|
114
113
|
ruby
|
115
114
|
|
116
115
|
DEPENDENCIES
|
data/README.rdoc
CHANGED
@@ -40,6 +40,21 @@ You can configure easy_captcha in "config/initializers/easy_captcha.rb", if you
|
|
40
40
|
# config.image_height = 40
|
41
41
|
# config.image_width = 140
|
42
42
|
|
43
|
+
# eSpeak (default disabled)
|
44
|
+
# config.espeak do |espeak|
|
45
|
+
# Amplitude, 0 to 200
|
46
|
+
# espeak.amplitude = 80..120
|
47
|
+
|
48
|
+
# Word gap. Pause between words
|
49
|
+
# espeak.gap = 80
|
50
|
+
|
51
|
+
# Pitch adjustment, 0 to 99
|
52
|
+
# espeak.pitch = 30..70
|
53
|
+
|
54
|
+
# Use voice file of this name from espeak-data/voices
|
55
|
+
# espeak.voice = nil
|
56
|
+
# end
|
57
|
+
|
43
58
|
# configure generator
|
44
59
|
# config.generator :default do |generator|
|
45
60
|
|
@@ -90,17 +105,18 @@ You can configure easy_captcha in "config/initializers/easy_captcha.rb", if you
|
|
90
105
|
<p><%= captcha_tag %></p>
|
91
106
|
<p><%= text_field_tag :captcha %></p>
|
92
107
|
<p><%= submit_tag 'Validate' %></p>
|
93
|
-
<% end %>
|
108
|
+
<% end %>
|
94
109
|
|
95
110
|
== Example app
|
96
111
|
You find an example app under: http://github.com/phatworx/easy_captcha_example
|
97
112
|
|
98
113
|
== History
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
114
|
+
* 0.1 init
|
115
|
+
* 0.2 cache support for high frequented sites
|
116
|
+
* 0.3 use generators, optimizations, update licence to same of all my plugins
|
117
|
+
* 0.4 generator support
|
118
|
+
* 0.5 (transparent) background support
|
119
|
+
* 0.6 espeak support for barrier-free support
|
104
120
|
|
105
121
|
== Maintainers
|
106
122
|
|
data/easy_captcha.gemspec
CHANGED
data/lib/easy_captcha.rb
CHANGED
@@ -3,10 +3,10 @@ require 'rails'
|
|
3
3
|
require 'action_controller'
|
4
4
|
require 'active_record'
|
5
5
|
require 'active_support'
|
6
|
-
require 'easy_captcha/parameters'
|
7
6
|
|
8
7
|
# Captcha-Plugin for Rails
|
9
8
|
module EasyCaptcha
|
9
|
+
autoload :Espeak, 'easy_captcha/espeak'
|
10
10
|
autoload :Captcha, 'easy_captcha/captcha'
|
11
11
|
autoload :Controller, 'easy_captcha/controller'
|
12
12
|
autoload :ModelHelpers, 'easy_captcha/model_helpers'
|
@@ -70,6 +70,26 @@ module EasyCaptcha
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
def espeak=(state)
|
74
|
+
if state === true
|
75
|
+
@espeak = Espeak.new
|
76
|
+
else
|
77
|
+
@espeak = false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def espeak(&block)
|
82
|
+
if block_given?
|
83
|
+
@espeak = Espeak.new &block
|
84
|
+
else
|
85
|
+
@espeak ||= false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def espeak?
|
90
|
+
not @espeak === false
|
91
|
+
end
|
92
|
+
|
73
93
|
# depracated
|
74
94
|
def method_missing name, *args
|
75
95
|
name = name.to_s # fix for jruby
|
@@ -3,7 +3,11 @@ module EasyCaptcha
|
|
3
3
|
class Controller < ActionController::Base
|
4
4
|
# captcha action send the generated image to browser
|
5
5
|
def captcha
|
6
|
-
|
6
|
+
if params[:format] == "wav" and EasyCaptcha.espeak?
|
7
|
+
send_data generate_speech_captcha, :disposition => 'inline', :type => 'audio/wav'
|
8
|
+
else
|
9
|
+
send_data generate_captcha, :disposition => 'inline', :type => 'image/png'
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
9
13
|
end
|
@@ -15,14 +15,16 @@ module EasyCaptcha
|
|
15
15
|
FileUtils.mkdir_p(EasyCaptcha.cache_temp_dir)
|
16
16
|
|
17
17
|
# select all generated captchas from cache
|
18
|
-
files = Dir.glob(EasyCaptcha.cache_temp_dir + "
|
19
|
-
|
18
|
+
files = Dir.glob(EasyCaptcha.cache_temp_dir + "*.png")
|
19
|
+
|
20
20
|
unless files.size < EasyCaptcha.cache_size
|
21
21
|
file = File.open(files.at(Kernel.rand(files.size)))
|
22
22
|
session[:captcha] = File.basename(file.path)
|
23
23
|
|
24
24
|
if file.mtime < EasyCaptcha.cache_expire.ago
|
25
25
|
File.unlink(file.path)
|
26
|
+
# remove speech version
|
27
|
+
File.unlink(file.path.gsub(/png\z/, "wav")) if File.exists?(file.path.gsub(/png\z/, "wav"))
|
26
28
|
else
|
27
29
|
return file.readlines.join
|
28
30
|
end
|
@@ -31,7 +33,10 @@ module EasyCaptcha
|
|
31
33
|
image = Captcha.new(generated_code).image
|
32
34
|
|
33
35
|
# write captcha for caching
|
34
|
-
File.open(
|
36
|
+
File.open(captcha_cache_path(generated_code), 'w') { |f| f.write image }
|
37
|
+
|
38
|
+
# write speech file if u create a new captcha image
|
39
|
+
EasyCaptcha.espeak.generate(generated_code, speech_captcha_cache_path(generated_code)) if EasyCaptcha.espeak?
|
35
40
|
|
36
41
|
# return image
|
37
42
|
image
|
@@ -40,6 +45,33 @@ module EasyCaptcha
|
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
48
|
+
# generate speech by captcha from session
|
49
|
+
def generate_speech_captcha
|
50
|
+
raise RuntimeError, "espeak disabled" unless EasyCaptcha.espeak?
|
51
|
+
if EasyCaptcha.cache
|
52
|
+
File.read(speech_captcha_cache_path(current_captcha_code))
|
53
|
+
else
|
54
|
+
wav_file = Tempfile.new("#{current_captcha_code}.wav")
|
55
|
+
EasyCaptcha.espeak.generate(current_captcha_code, wav_file.path)
|
56
|
+
File.read(wav_file.path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# return cache path of captcha image
|
61
|
+
def captcha_cache_path(code)
|
62
|
+
"#{EasyCaptcha.cache_temp_dir}/#{code}.png"
|
63
|
+
end
|
64
|
+
|
65
|
+
# return cache path of speech captcha
|
66
|
+
def speech_captcha_cache_path(code)
|
67
|
+
"#{EasyCaptcha.cache_temp_dir}/#{code}.wav"
|
68
|
+
end
|
69
|
+
|
70
|
+
# current active captcha from session
|
71
|
+
def current_captcha_code
|
72
|
+
session[:captcha]
|
73
|
+
end
|
74
|
+
|
43
75
|
# generate captcha code, save in session and return
|
44
76
|
def generate_captcha_code
|
45
77
|
session[:captcha] = EasyCaptcha.length.times.collect { EasyCaptcha.chars[rand(EasyCaptcha.chars.size)] }.join
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
# espeak wrapper
|
3
|
+
class Espeak
|
4
|
+
|
5
|
+
# generator for captcha images
|
6
|
+
def initialize(&block)
|
7
|
+
defaults
|
8
|
+
yield self if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
# set default values
|
12
|
+
def defaults
|
13
|
+
@amplitude = 80..120
|
14
|
+
@pitch = 30..70
|
15
|
+
@gap = 80
|
16
|
+
@voice = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_writer :amplitude, :pitch, :gap, :voice
|
20
|
+
|
21
|
+
# return amplitude
|
22
|
+
def amplitude
|
23
|
+
if @amplitude.is_a? Range
|
24
|
+
@amplitude.to_a.sort_by { rand }.first
|
25
|
+
else
|
26
|
+
@amplitude.to_i
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# return amplitude
|
31
|
+
def pitch
|
32
|
+
if @pitch.is_a? Range
|
33
|
+
@pitch.to_a.sort_by { rand }.first
|
34
|
+
else
|
35
|
+
@pitch.to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def gap
|
40
|
+
@gap.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def voice
|
44
|
+
if @voice.is_a? Array
|
45
|
+
v = @voice.sort_by { rand }.first
|
46
|
+
else
|
47
|
+
v = @voice
|
48
|
+
end
|
49
|
+
|
50
|
+
v.try :gsub, /[^A-Za-z0-9\-\+]/, ""
|
51
|
+
end
|
52
|
+
|
53
|
+
# generate wav file by captcha
|
54
|
+
def generate(captcha, wav_file)
|
55
|
+
# get code
|
56
|
+
if captcha.is_a? Captcha
|
57
|
+
code = captcha.code
|
58
|
+
elsif captcha.is_a? String
|
59
|
+
code = captcha
|
60
|
+
else
|
61
|
+
raise ArgumentError, "invalid captcha"
|
62
|
+
end
|
63
|
+
|
64
|
+
# add spaces
|
65
|
+
code = code.each_char.to_a.join(" ")
|
66
|
+
|
67
|
+
cmd = "espeak -g 10"
|
68
|
+
cmd << " -a #{amplitude}" unless @amplitude.nil?
|
69
|
+
cmd << " -p #{pitch}" unless @pitch.nil?
|
70
|
+
cmd << " -g #{gap}" unless @gap.nil?
|
71
|
+
cmd << " -v '#{voice}'" unless @voice.nil?
|
72
|
+
cmd << " -w #{wav_file} '#{code}'"
|
73
|
+
|
74
|
+
%x{#{cmd}}
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
data/lib/easy_captcha/version.rb
CHANGED
@@ -18,6 +18,21 @@ EasyCaptcha.setup do |config|
|
|
18
18
|
# config.image_height = 40
|
19
19
|
# config.image_width = 140
|
20
20
|
|
21
|
+
# eSpeak
|
22
|
+
# config.espeak do |espeak|
|
23
|
+
# Amplitude, 0 to 200
|
24
|
+
# espeak.amplitude = 80..120
|
25
|
+
|
26
|
+
# Word gap. Pause between words
|
27
|
+
# espeak.gap = 80
|
28
|
+
|
29
|
+
# Pitch adjustment, 0 to 99
|
30
|
+
# espeak.pitch = 30..70
|
31
|
+
|
32
|
+
# Use voice file of this name from espeak-data/voices
|
33
|
+
# espeak.voice = nil
|
34
|
+
# end
|
35
|
+
|
21
36
|
# configure generator
|
22
37
|
# config.generator :default do |generator|
|
23
38
|
|
@@ -48,4 +63,4 @@ EasyCaptcha.setup do |config|
|
|
48
63
|
# generator.blur_radius = 1
|
49
64
|
# generator.blur_sigma = 2
|
50
65
|
# end
|
51
|
-
end
|
66
|
+
end
|
data/spec/espeak_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe EasyCaptcha::Espeak do
|
5
|
+
context "check default values" do
|
6
|
+
subject { EasyCaptcha::Espeak.new }
|
7
|
+
|
8
|
+
its(:amplitude) { (80..120).to_a.should include(subject) }
|
9
|
+
its(:pitch) { (30..70).to_a.should include(subject) }
|
10
|
+
its(:gap) { should eq 80 }
|
11
|
+
its(:voice) { should be_nil }
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
context "check config: voices" do
|
16
|
+
let(:voices) { ['german', 'german+m1'] }
|
17
|
+
subject do
|
18
|
+
EasyCaptcha::Espeak.new do |config|
|
19
|
+
config.voice = voices
|
20
|
+
end
|
21
|
+
end
|
22
|
+
its(:voice) { voices.should include(subject) }
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -129,11 +129,11 @@ files:
|
|
129
129
|
- lib/easy_captcha/captcha.rb
|
130
130
|
- lib/easy_captcha/controller.rb
|
131
131
|
- lib/easy_captcha/controller_helpers.rb
|
132
|
+
- lib/easy_captcha/espeak.rb
|
132
133
|
- lib/easy_captcha/generator.rb
|
133
134
|
- lib/easy_captcha/generator/base.rb
|
134
135
|
- lib/easy_captcha/generator/default.rb
|
135
136
|
- lib/easy_captcha/model_helpers.rb
|
136
|
-
- lib/easy_captcha/parameters.rb
|
137
137
|
- lib/easy_captcha/routes.rb
|
138
138
|
- lib/easy_captcha/version.rb
|
139
139
|
- lib/easy_captcha/view_helpers.rb
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/generators/templates/easy_captcha.rb
|
142
142
|
- resources/captcha.ttf
|
143
143
|
- spec/easy_captcha_spec.rb
|
144
|
+
- spec/espeak_spec.rb
|
144
145
|
- spec/spec.opts
|
145
146
|
- spec/spec_helper.rb
|
146
147
|
homepage: http://github.com/phatworx/easy_captcha
|
@@ -156,9 +157,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
157
|
- - ! '>='
|
157
158
|
- !ruby/object:Gem::Version
|
158
159
|
version: '0'
|
159
|
-
segments:
|
160
|
-
- 0
|
161
|
-
hash: 4538857605889255644
|
162
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
161
|
none: false
|
164
162
|
requirements:
|
@@ -167,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
165
|
version: '0'
|
168
166
|
requirements: []
|
169
167
|
rubyforge_project:
|
170
|
-
rubygems_version: 1.8.
|
168
|
+
rubygems_version: 1.8.24
|
171
169
|
signing_key:
|
172
170
|
specification_version: 3
|
173
171
|
summary: Captcha-Plugin for Rails
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module ActionDispatch
|
2
|
-
module Http
|
3
|
-
module Parameters
|
4
|
-
private
|
5
|
-
|
6
|
-
# TODO: Validate that the characters are UTF-8. If they aren't,
|
7
|
-
# you'll get a weird error down the road, but our form handling
|
8
|
-
# should really prevent that from happening
|
9
|
-
def encode_params(params)
|
10
|
-
return params unless "ruby".encoding_aware?
|
11
|
-
|
12
|
-
if params.is_a?(String)
|
13
|
-
return params.dup.force_encoding("UTF-8").encode!
|
14
|
-
elsif !params.is_a?(Hash)
|
15
|
-
return params
|
16
|
-
end
|
17
|
-
|
18
|
-
params.each do |k, v|
|
19
|
-
case v
|
20
|
-
when Hash
|
21
|
-
encode_params(v)
|
22
|
-
when Array
|
23
|
-
v.map! {|el| encode_params(el) }
|
24
|
-
else
|
25
|
-
encode_params(v)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|