deathbycaptcha 4.0.2 → 4.1.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/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)