easy_captcha 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|