deathbycaptcha 4.0.2 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,6 +12,11 @@ Thread-safety note
12
12
 
13
13
  The API is thread-safe, which means it is perfectly fine to share a client instance between multiple threads.
14
14
 
15
+ Latest version
16
+ --------------
17
+
18
+ The latest version of this API is 4.1.1.
19
+
15
20
  Installation
16
21
  ------------
17
22
 
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.platform = Gem::Platform::RUBY
12
12
  s.authors = ["Rafael Barbolo Lopes, Rafael Ivan Garcia"]
13
13
  s.email = ["tech@infosimples.com.br"]
14
- s.homepage = "http://github.com/infosimples/deathbycaptcha"
14
+ s.homepage = "http://www.infosimples.com.br/en/open-source/captcha-solving-api/"
15
15
  s.summary = %q{Ruby API for DeathByCaptcha (Captcha Solver as a Service)}
16
16
  s.description = %q{Ruby API for DeathByCaptcha (Captcha Solver as a Service)}
17
17
 
@@ -11,7 +11,7 @@ module DeathByCaptcha
11
11
 
12
12
  attr_accessor :config
13
13
 
14
- def initialize(username, password, extra={})
14
+ def initialize(username, password, extra = {})
15
15
  data = {
16
16
  :is_verbose => false, # If true, prints messages during execution
17
17
  :logger_output => STDOUT, # Logger output path or IO instance
@@ -23,11 +23,9 @@ module DeathByCaptcha
23
23
  :http_base_url => 'http://api.deathbycaptcha.com/api', # Base HTTP API url
24
24
  :http_response_type => 'application/json', # Preferred HTTP API server's response content type, do not change
25
25
  :socket_host => 'api.deathbycaptcha.com', # Socket API server's host
26
- :socket_port => (8123..8130).map {|p| p}, # Socket API server's ports range
26
+ :socket_port => (8123..8130).map { |p| p }, # Socket API server's ports range
27
27
  :username => username, # DeathByCaptcha username
28
- :password_hashed => Digest::SHA1.hexdigest(password), # DeathByCaptcha user's password encrypted
29
- :password => '', # DeathByCaptcha user's password not encrypted
30
- :password_is_hashed => true # True, if the password is hashed
28
+ :password => password, # DeathByCaptcha user's password not encrypted
31
29
  }.merge(extra)
32
30
 
33
31
  @config = DeathByCaptcha::Config.new(data) # Config instance
@@ -70,13 +68,6 @@ module DeathByCaptcha
70
68
  raise DeathByCaptcha::Errors::NotImplemented
71
69
  end
72
70
 
73
- #
74
- # Remove an unsolved CAPTCHA
75
- #
76
- def remove(cid)
77
- raise DeathByCaptcha::Errors::NotImplemented
78
- end
79
-
80
71
  #
81
72
  # Upload a CAPTCHA
82
73
  #
@@ -84,7 +75,7 @@ module DeathByCaptcha
84
75
  # whether the CAPTCHA is case-sensitive or not. Returns CAPTCHA details
85
76
  # on success.
86
77
  #
87
- def upload(captcha, options={})
78
+ def upload(captcha, options = {})
88
79
  raise DeathByCaptcha::Errors::NotImplemented
89
80
  end
90
81
 
@@ -97,27 +88,30 @@ module DeathByCaptcha
97
88
  # timeout (in seconds). Removes unsolved CAPTCHAs. Returns CAPTCHA
98
89
  # details if (correctly) solved.
99
90
  #
100
- def decode(captcha, options={})
101
- options = {:timeout => config.default_timeout, :is_case_sensitive => false, :is_raw_content => false}.merge(options)
91
+ def decode(captcha, options = {})
92
+ options = {
93
+ :timeout => config.default_timeout,
94
+ :is_case_sensitive => false,
95
+ :is_raw_content => false
96
+ }.merge(options)
97
+
102
98
  deadline = Time.now + options[:timeout]
103
99
  c = upload(captcha, options)
104
100
  if c
101
+
105
102
  while deadline > Time.now and (c['text'].nil? or c['text'].empty?)
106
103
  sleep(config.polls_interval)
107
104
  c = get_captcha(c['captcha'])
108
105
  end
109
106
 
110
107
  if c['text']
111
- if c['is_correct']
112
- return c
113
- end
108
+ return c if c['is_correct']
114
109
  else
115
110
  remove(c['captcha'])
116
111
  end
117
112
 
118
113
  end
119
114
 
120
-
121
115
  end
122
116
 
123
117
  #
@@ -129,11 +123,7 @@ module DeathByCaptcha
129
123
  # Return a hash with the user's credentials
130
124
  #
131
125
  def userpwd
132
- if config.password_is_hashed
133
- return {:username => config.username, :password => config.password_hashed, :is_hashed => '1'}
134
- else
135
- return {:username => config.username, :password => config.password}
136
- end
126
+ { :username => config.username, :password => config.password }
137
127
  end
138
128
 
139
129
  #
@@ -144,7 +134,7 @@ module DeathByCaptcha
144
134
  #
145
135
  # Log a command and a message
146
136
  #
147
- def log(cmd, msg='')
137
+ def log(cmd, msg = '')
148
138
  if @config.is_verbose
149
139
  @logger.info "#{cmd}: #{msg}"
150
140
  end
@@ -159,22 +149,24 @@ module DeathByCaptcha
159
149
  # => a url if it's a String and starts with 'http://'
160
150
  # => a filesystem path otherwise
161
151
  #
162
- def load_file(captcha, is_raw_content=false)
152
+ def load_file(captcha, is_raw_content = false)
153
+
163
154
  file = nil
155
+
164
156
  if is_raw_content
165
157
  # Create a temporary file, write the raw content and return it
166
158
  tmp_file_path = File.join(Dir.tmpdir, "captcha_#{Time.now.to_i}_#{rand}")
167
- File.open(tmp_file_path, 'wb') {|f| f.write captcha}
159
+ File.open(tmp_file_path, 'wb') { |f| f.write captcha }
168
160
  file = File.open(tmp_file_path, 'r')
169
161
 
170
162
  elsif captcha.kind_of? File
171
163
  # simply return the file
172
164
  file = captcha
173
165
 
174
- elsif captcha.kind_of? String and captcha[0,7] == 'http://'
166
+ elsif captcha.kind_of? String and captcha.match(/^https?:\/\//i)
175
167
  # Create a temporary file, download the file, write it to tempfile and return it
176
168
  tmp_file_path = File.join(Dir.tmpdir, "captcha_#{Time.now.to_i}_#{rand}")
177
- File.open(tmp_file_path, 'w') {|f| f.write RestClient.get(captcha)}
169
+ File.open(tmp_file_path, 'wb') { |f| f.write RestClient.get(captcha) }
178
170
  file = File.open(tmp_file_path, 'r')
179
171
 
180
172
  else
@@ -189,9 +181,10 @@ module DeathByCaptcha
189
181
  raise DeathByCaptcha::Errors::CaptchaOverflow
190
182
  end
191
183
 
192
- return file
184
+ file
185
+
193
186
  end
194
187
 
195
188
  end
196
189
 
197
- end
190
+ end
@@ -1,14 +1,14 @@
1
1
  module DeathByCaptcha
2
+
2
3
  module Errors
3
4
 
4
-
5
5
  #
6
6
  # Custom Error class for rescuing from DeathByCaptcha API errors
7
7
  #
8
8
  class Error < StandardError
9
9
 
10
10
  def initialize(message)
11
- super "#{message} (DEATHBYCAPTCHA API ERROR)"
11
+ super("#{message} (DEATHBYCAPTCHA API ERROR)")
12
12
  end
13
13
 
14
14
  end
@@ -18,7 +18,7 @@ module DeathByCaptcha
18
18
  #
19
19
  class NotImplemented < Error
20
20
  def initialize
21
- super 'The requested functionality was not implemented'
21
+ super('The requested functionality was not implemented')
22
22
  end
23
23
  end
24
24
 
@@ -27,7 +27,7 @@ module DeathByCaptcha
27
27
  #
28
28
  class CallError < Error
29
29
  def initialize
30
- super 'HTTP call failed'
30
+ super('HTTP call failed')
31
31
  end
32
32
  end
33
33
 
@@ -36,7 +36,7 @@ module DeathByCaptcha
36
36
  #
37
37
  class AccessDenied < Error
38
38
  def initialize
39
- super 'Access denied, please check your credentials and/or balance'
39
+ super('Access denied, please check your credentials and/or balance')
40
40
  end
41
41
  end
42
42
 
@@ -45,7 +45,7 @@ module DeathByCaptcha
45
45
  #
46
46
  class CaptchaEmpty
47
47
  def initialize
48
- super 'CAPTCHA image is empty or could not be loaded'
48
+ super('CAPTCHA image is empty or could not be loaded')
49
49
  end
50
50
  end
51
51
 
@@ -54,9 +54,16 @@ module DeathByCaptcha
54
54
  #
55
55
  class CaptchaOverflow
56
56
  def initialize
57
- super 'CAPTCHA image is too big'
57
+ super('CAPTCHA image is too big')
58
+ end
59
+ end
60
+
61
+ class ServiceOverload
62
+ def initialize
63
+ super('CAPTCHA was rejected due to service overload, try again later')
58
64
  end
59
65
  end
60
66
 
61
67
  end
68
+
62
69
  end
@@ -25,22 +25,23 @@ module DeathByCaptcha
25
25
  not call("captcha/#{cid}/remove", userpwd)['captcha']
26
26
  end
27
27
 
28
- def a(nome, test=false, valor="verdade")
29
- puts nome,test,valor
30
- end
31
-
32
28
  #
33
29
  # Protected methods.
34
30
  #
35
31
  protected
36
32
 
37
- def upload(captcha, options={})
38
- options = {:is_case_sensitive => false, :is_raw_content => false}.merge(options)
33
+ def upload(captcha, options = {})
34
+ options = {
35
+ :is_case_sensitive => false,
36
+ :is_raw_content => false
37
+ }.merge(options)
38
+
39
39
  data = userpwd
40
40
  data[:swid] = config.software_vendor_id
41
41
  data[:is_case_sensitive] = options[:is_case_sensitive] ? 1 : 0
42
42
  data[:captchafile] = load_file(captcha, options[:is_raw_content])
43
43
  response = call('captcha', data)
44
+
44
45
  return response if response['captcha']
45
46
  end
46
47
 
@@ -49,7 +50,9 @@ module DeathByCaptcha
49
50
  #
50
51
  private
51
52
 
52
- def call(cmd, payload={}, headers={})
53
+ def call(cmd, payload = {}, headers = {})
54
+
55
+ headers = {} unless headers.is_a?(Hash)
53
56
  headers['Accept'] = config.http_response_type if headers['Accept'].nil?
54
57
  headers['User-Agent'] = config.api_version if headers['User-Agent'].nil?
55
58
 
@@ -74,6 +77,9 @@ module DeathByCaptcha
74
77
  rescue RestClient::RequestFailed => exc
75
78
  raise DeathByCaptcha::Errors::AccessDenied
76
79
 
80
+ rescue RestClient::ServiceUnavailable => exc
81
+ raise DeathByCaptcha::Errors::ServiceOverload
82
+
77
83
  else
78
84
  raise DeathByCaptcha::Errors::CallError
79
85
 
@@ -85,8 +91,7 @@ module DeathByCaptcha
85
91
 
86
92
  end
87
93
 
88
-
89
- def self.http_client(username, password, extra={})
94
+ def self.http_client(username, password, extra = {})
90
95
  DeathByCaptcha::HTTPClient.new(username, password, extra)
91
96
  end
92
97
 
@@ -25,7 +25,7 @@ module DeathByCaptcha
25
25
  end
26
26
 
27
27
  def get_user
28
- call('user', userpwd)
28
+ call('user')
29
29
  end
30
30
 
31
31
  def get_captcha(cid)
@@ -33,19 +33,8 @@ module DeathByCaptcha
33
33
  end
34
34
 
35
35
  def report(cid)
36
- call("captcha/#{cid}/report", userpwd)[:is_correct]
37
-
38
- data = userpwd
39
- data['captcha'] = cid
40
- not call('report', data)[:is_correct]
41
- end
42
-
43
- def remove(cid)
44
- not call("captcha/#{cid}/remove", userpwd)[:captcha]
45
-
46
- data = userpwd
47
- data['captcha'] = cid
48
- not call('remove', data)[:captcha]
36
+ data = { 'captcha' => cid }
37
+ call('report', data)[:is_correct]
49
38
  end
50
39
 
51
40
  #
@@ -53,14 +42,13 @@ module DeathByCaptcha
53
42
  #
54
43
  protected
55
44
 
56
- def upload(captcha, is_case_sensitive=false, is_raw_content=false)
57
- data = userpwd
58
- data[:captcha] = Base64.encode64(load_file(captcha, is_raw_content).read)
45
+ def upload(captcha, is_case_sensitive = false, is_raw_content = false)
46
+ data = {
47
+ :captcha => Base64.encode64(load_file(captcha, is_raw_content).read),
48
+ :is_case_sensitive => (is_case_sensitive ? 1 : 0)
49
+ }
59
50
 
60
- data[:is_case_sensitive] = is_case_sensitive ? 1 : 0
61
- response = call('upload', data)
62
-
63
- response
51
+ call('upload', data)
64
52
  end
65
53
 
66
54
  #
@@ -178,13 +166,13 @@ module DeathByCaptcha
178
166
  end
179
167
  end
180
168
 
181
- return buf[0, buf.size - 1] if buf.size > 0
169
+ return buf[0, buf.size] if buf.size > 0
182
170
  raise IOError.new('recv() timed out')
183
171
  end
184
172
 
185
173
  def call(cmd, data = {})
186
174
  data = {} if data.nil?
187
- data.merge!({:cmd => cmd, :version => config.api_version})
175
+ data.merge!({ :cmd => cmd, :version => config.api_version })
188
176
 
189
177
  request = data.to_json
190
178
  log('SEND', request.to_s)
@@ -192,6 +180,10 @@ module DeathByCaptcha
192
180
  response = nil
193
181
 
194
182
  (0...1).each do
183
+ if not @socket and cmd != 'login'
184
+ call('login', userpwd)
185
+ end
186
+
195
187
  # Locks other threads.
196
188
  # If another thread has already acquired the lock, this thread will be locked.
197
189
  @mutex.lock
@@ -241,7 +233,6 @@ module DeathByCaptcha
241
233
 
242
234
  end
243
235
 
244
-
245
236
  def self.socket_client(username, password, extra={})
246
237
  DeathByCaptcha::SocketClient.new(username, password, extra)
247
238
  end
@@ -1,4 +1,4 @@
1
1
  module DeathByCaptcha
2
- VERSION = "4.0.2"
3
- API_VERSION = "DBC/Ruby v4.0.2"
2
+ VERSION = "4.1.1"
3
+ API_VERSION = "DBC/Ruby v4.1.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deathbycaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-26 00:00:00.000000000 -03:00
13
- default_executable:
12
+ date: 2011-10-11 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rest-client
17
- requirement: &2153340400 !ruby/object:Gem::Requirement
16
+ requirement: &2160211420 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ~>
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: 1.6.1
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *2153340400
24
+ version_requirements: *2160211420
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: json
28
- requirement: &2153339900 !ruby/object:Gem::Requirement
27
+ requirement: &2160210400 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ~>
@@ -33,7 +32,7 @@ dependencies:
33
32
  version: 1.4.6
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *2153339900
35
+ version_requirements: *2160210400
37
36
  description: Ruby API for DeathByCaptcha (Captcha Solver as a Service)
38
37
  email:
39
38
  - tech@infosimples.com.br
@@ -54,8 +53,7 @@ files:
54
53
  - lib/deathbycaptcha/http_client.rb
55
54
  - lib/deathbycaptcha/socket_client.rb
56
55
  - lib/deathbycaptcha/version.rb
57
- has_rdoc: true
58
- homepage: http://github.com/infosimples/deathbycaptcha
56
+ homepage: http://www.infosimples.com.br/en/open-source/captcha-solving-api/
59
57
  licenses: []
60
58
  post_install_message:
61
59
  rdoc_options: []
@@ -75,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
73
  version: '0'
76
74
  requirements: []
77
75
  rubyforge_project: deathbycaptcha
78
- rubygems_version: 1.6.2
76
+ rubygems_version: 1.8.10
79
77
  signing_key:
80
78
  specification_version: 3
81
79
  summary: Ruby API for DeathByCaptcha (Captcha Solver as a Service)