deathbycaptcha 4.1.2 → 4.1.3

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,11 +12,6 @@ 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
-
20
15
  Installation
21
16
  ------------
22
17
 
@@ -38,23 +33,23 @@ Examples
38
33
  require 'deathbycaptcha'
39
34
 
40
35
  client = DeathByCaptcha.http_client('myusername', 'mypassword')
41
-
36
+
42
37
  #### Socket client
43
38
 
44
39
  require 'deathbycaptcha'
45
40
 
46
41
  client = DeathByCaptcha.socket_client('myusername', 'mypassword')
47
-
42
+
48
43
  #### Verbose mode (for debugging purposes)
49
44
 
50
45
  client.config.is_verbose = true
51
-
46
+
52
47
  #### Decoding captcha
53
48
 
54
49
  ##### From URL
55
-
50
+
56
51
  response = client.decode 'http://www.phpcaptcha.org/securimage/securimage_show.php'
57
-
52
+
58
53
  puts "captcha id: #{response['captcha']}, solution: #{response['text']}, is_correct: #{response['is_correct']}}"
59
54
 
60
55
  ##### From file path
@@ -62,7 +57,7 @@ Examples
62
57
  response = client.decode 'path/to/my/captcha/file'
63
58
 
64
59
  puts "captcha id: #{response['captcha']}, solution: #{response['text']}, is_correct: #{response['is_correct']}}"
65
-
60
+
66
61
  ##### From a file
67
62
 
68
63
  file = File.open('path/to/my/captcha/file', 'r')
@@ -70,7 +65,7 @@ Examples
70
65
  response = client.decode file
71
66
 
72
67
  puts "captcha id: #{response['captcha']}, solution: #{response['text']}, is_correct: #{response['is_correct']}}"
73
-
68
+
74
69
  ##### From raw content
75
70
 
76
71
  raw_content = File.open('path/to/my/captcha/file', 'r').read
@@ -80,9 +75,9 @@ Examples
80
75
  puts "captcha id: #{response['captcha']}, solution: #{response['text']}, is_correct: #{response['is_correct']}}"
81
76
 
82
77
  #### Get the solution of a captcha
83
-
78
+
84
79
  puts client.get_captcha('130920620')['text'] # where 130920620 is the captcha id
85
-
80
+
86
81
  #### Get user account information
87
82
 
88
83
  puts client.get_user
@@ -1,9 +1,9 @@
1
1
  require 'deathbycaptcha/version'
2
2
  require 'deathbycaptcha/config'
3
- require 'deathbycaptcha/error'
3
+ require 'deathbycaptcha/errors'
4
4
  require 'deathbycaptcha/client'
5
5
  require 'deathbycaptcha/http_client'
6
6
  require 'deathbycaptcha/socket_client'
7
7
 
8
- module DeathByCaptcha
8
+ module DeathByCaptcha
9
9
  end
@@ -3,73 +3,72 @@ require 'digest/sha1'
3
3
  require 'rest_client'
4
4
 
5
5
  module DeathByCaptcha
6
-
6
+
7
7
  #
8
8
  # DeathByCaptcha API Client
9
9
  #
10
10
  class Client
11
-
11
+
12
12
  attr_accessor :config
13
-
13
+
14
14
  def initialize(username, password, extra = {})
15
15
  data = {
16
- :is_verbose => false, # If true, prints messages during execution
17
- :logger_output => STDOUT, # Logger output path or IO instance
18
- :api_version => API_VERSION, # API version (used as user-agent with http requests)
19
- :software_vendor_id => 0, # API unique software ID
20
- :max_captcha_file_size => 64 * 1024, # Maximum CAPTCHA image filesize, currently 64K
21
- :default_timeout => 60, # Default CAPTCHA timeout
22
- :polls_interval => 5, # Default decode polling interval
23
- :http_base_url => 'http://api.deathbycaptcha.com/api', # Base HTTP API url
24
- :http_response_type => 'application/json', # Preferred HTTP API server's response content type, do not change
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
27
- :username => username, # DeathByCaptcha username
28
- :password => password, # DeathByCaptcha user's password not encrypted
16
+ :is_verbose => false, # If true, prints messages during execution.
17
+ :logger_output => STDOUT, # Logger output path or IO instance.
18
+ :api_version => API_VERSION, # API version (used as user-agent with http requests).
19
+ :software_vendor_id => 0, # API unique software ID.
20
+ :max_captcha_file_size => (64 * 1024), # Maximum CAPTCHA image filesize, currently 64K.
21
+ :default_timeout => 60, # Default CAPTCHA timeout.
22
+ :polls_interval => 5, # Default decode polling interval.
23
+ :http_base_url => 'http://api.dbcapi.me/api', # Base HTTP API url.
24
+ :http_response_type => 'application/json', # Preferred HTTP API server's response content type, do not change.
25
+ :socket_host => 'api.dbcapi.me', # Socket API server's host.
26
+ :socket_ports => (8123..8130).map { |p| p }, # Socket API server's ports range.
27
+ :username => username, # DeathByCaptcha username.
28
+ :password => password, # DeathByCaptcha user's password not encrypted.
29
29
  }.merge(extra)
30
-
31
- @config = DeathByCaptcha::Config.new(data) # Config instance
32
- @logger = Logger.new(@config.logger_output) # Logger
33
-
30
+
31
+ @config = DeathByCaptcha::Config.new(data) # Config instance.
32
+ @logger = Logger.new(@config.logger_output) # Logger.
34
33
  end
35
-
34
+
36
35
  #
37
- # Fetch the user's details -- balance, rate and banned status
36
+ # Fetch the user's details -- balance, rate and banned status.
38
37
  #
39
38
  def get_user
40
39
  raise DeathByCaptcha::Errors::NotImplemented
41
40
  end
42
-
41
+
43
42
  #
44
- # Fetch the user's balance (in US cents)
43
+ # Fetch the user's balance (in US cents).
45
44
  #
46
45
  def get_balance
47
46
  raise DeathByCaptcha::Errors::NotImplemented
48
47
  end
49
-
48
+
50
49
  #
51
- # Fetch a CAPTCHA details -- its numeric ID, text and correctness
50
+ # Fetch a CAPTCHA details -- its numeric ID, text and correctness.
52
51
  #
53
52
  def get_captcha(cid)
54
53
  raise DeathByCaptcha::Errors::NotImplemented
55
54
  end
56
-
55
+
57
56
  #
58
- # Fetch a CAPTCHA text
57
+ # Fetch a CAPTCHA text.
59
58
  #
60
59
  def get_text(cid)
61
60
  raise DeathByCaptcha::Errors::NotImplemented
62
61
  end
63
-
62
+
64
63
  #
65
- # Report a CAPTCHA as incorrectly solved
64
+ # Report a CAPTCHA as incorrectly solved.
66
65
  #
67
66
  def report(cid)
68
67
  raise DeathByCaptcha::Errors::NotImplemented
69
68
  end
70
-
69
+
71
70
  #
72
- # Upload a CAPTCHA
71
+ # Upload a CAPTCHA.
73
72
  #
74
73
  # Accepts file names, file objects or urls, and an optional flag telling
75
74
  # whether the CAPTCHA is case-sensitive or not. Returns CAPTCHA details
@@ -78,7 +77,7 @@ module DeathByCaptcha
78
77
  def upload(captcha, options = {})
79
78
  raise DeathByCaptcha::Errors::NotImplemented
80
79
  end
81
-
80
+
82
81
  #
83
82
  # Try to solve a CAPTCHA.
84
83
  #
@@ -90,47 +89,46 @@ module DeathByCaptcha
90
89
  #
91
90
  def decode(captcha, options = {})
92
91
  options = {
93
- :timeout => config.default_timeout,
94
- :is_case_sensitive => false,
95
- :is_raw_content => false
92
+ :timeout => config.default_timeout,
93
+ :is_case_sensitive => false,
94
+ :is_raw_content => false
96
95
  }.merge(options)
97
-
96
+
98
97
  deadline = Time.now + options[:timeout]
99
98
  c = upload(captcha, options)
100
99
  if c
101
-
100
+
102
101
  while deadline > Time.now and (c['text'].nil? or c['text'].empty?)
103
102
  sleep(config.polls_interval)
104
103
  c = get_captcha(c['captcha'])
105
104
  end
106
-
105
+
107
106
  if c['text']
108
107
  return c if c['is_correct']
109
108
  else
110
109
  remove(c['captcha'])
111
110
  end
112
-
111
+
113
112
  end
114
-
115
113
  end
116
-
114
+
117
115
  #
118
116
  # Protected methods.
119
117
  #
120
118
  protected
121
-
119
+
122
120
  #
123
121
  # Return a hash with the user's credentials
124
122
  #
125
123
  def userpwd
126
124
  { :username => config.username, :password => config.password }
127
125
  end
128
-
126
+
129
127
  #
130
128
  # Private methods.
131
129
  #
132
130
  private
133
-
131
+
134
132
  #
135
133
  # Log a command and a message
136
134
  #
@@ -150,41 +148,41 @@ module DeathByCaptcha
150
148
  # => a filesystem path otherwise
151
149
  #
152
150
  def load_file(captcha, is_raw_content = false)
153
-
151
+
154
152
  file = nil
155
-
153
+
156
154
  if is_raw_content
157
155
  # Create a temporary file, write the raw content and return it
158
156
  tmp_file_path = File.join(Dir.tmpdir, "captcha_#{Time.now.to_i}_#{rand}")
159
157
  File.open(tmp_file_path, 'wb') { |f| f.write captcha }
160
158
  file = File.open(tmp_file_path, 'r')
161
-
159
+
162
160
  elsif captcha.kind_of? File
163
161
  # simply return the file
164
162
  file = captcha
165
-
163
+
166
164
  elsif captcha.kind_of? String and captcha.match(/^https?:\/\//i)
167
165
  # Create a temporary file, download the file, write it to tempfile and return it
168
166
  tmp_file_path = File.join(Dir.tmpdir, "captcha_#{Time.now.to_i}_#{rand}")
169
167
  File.open(tmp_file_path, 'wb') { |f| f.write RestClient.get(captcha) }
170
168
  file = File.open(tmp_file_path, 'r')
171
-
169
+
172
170
  else
173
171
  # Return the File opened
174
172
  file = File.open(captcha, 'r')
175
-
173
+
176
174
  end
177
-
175
+
178
176
  if file.nil?
179
177
  raise DeathByCaptcha::Errors::CaptchaEmpty
180
178
  elsif config.max_captcha_file_size <= File.size?(file).to_i
181
179
  raise DeathByCaptcha::Errors::CaptchaOverflow
182
180
  end
183
-
181
+
184
182
  file
185
-
183
+
186
184
  end
187
-
185
+
188
186
  end
189
-
187
+
190
188
  end
@@ -1,4 +1,4 @@
1
- module DeathByCaptcha
1
+ module DeathByCaptcha
2
2
 
3
3
  #
4
4
  # Config class
@@ -6,7 +6,7 @@ module DeathByCaptcha
6
6
  #
7
7
  class Config
8
8
 
9
- def initialize(data={})
9
+ def initialize(data = {})
10
10
  @data = {}
11
11
  update!(data)
12
12
  end
@@ -38,5 +38,5 @@ module DeathByCaptcha
38
38
  end
39
39
 
40
40
  end
41
-
41
+
42
42
  end
@@ -1,9 +1,9 @@
1
1
  module DeathByCaptcha
2
-
2
+
3
3
  module Errors
4
-
4
+
5
5
  #
6
- # Custom Error class for rescuing from DeathByCaptcha API errors
6
+ # Custom Error class for rescuing from DeathByCaptcha API errors.
7
7
  #
8
8
  class Error < StandardError
9
9
 
@@ -14,56 +14,56 @@ module DeathByCaptcha
14
14
  end
15
15
 
16
16
  #
17
- # Raised when a method tries to access a not implemented method
17
+ # Raised when a method tries to access a not implemented method.
18
18
  #
19
19
  class NotImplemented < Error
20
20
  def initialize
21
21
  super('The requested functionality was not implemented')
22
22
  end
23
23
  end
24
-
24
+
25
25
  #
26
- # Raised when a HTTP call fails
26
+ # Raised when a HTTP call fails.
27
27
  #
28
28
  class CallError < Error
29
29
  def initialize
30
30
  super('HTTP call failed')
31
31
  end
32
32
  end
33
-
33
+
34
34
  #
35
- # Raised when the user is not allowed to access the API
35
+ # Raised when the user is not allowed to access the API.
36
36
  #
37
37
  class AccessDenied < Error
38
38
  def initialize
39
39
  super('Access denied, please check your credentials and/or balance')
40
40
  end
41
41
  end
42
-
42
+
43
43
  #
44
- # Raised when the captcha file could not be loaded or is empty
44
+ # Raised when the captcha file could not be loaded or is empty.
45
45
  #
46
46
  class CaptchaEmpty
47
47
  def initialize
48
48
  super('CAPTCHA image is empty or could not be loaded')
49
49
  end
50
50
  end
51
-
51
+
52
52
  #
53
- # Raised when the size of the captcha file is too big
53
+ # Raised when the size of the captcha file is too big.
54
54
  #
55
55
  class CaptchaOverflow
56
56
  def initialize
57
57
  super('CAPTCHA image is too big')
58
58
  end
59
59
  end
60
-
60
+
61
61
  class ServiceOverload
62
62
  def initialize
63
63
  super('CAPTCHA was rejected due to service overload, try again later')
64
64
  end
65
65
  end
66
-
66
+
67
67
  end
68
-
68
+
69
69
  end
@@ -3,16 +3,16 @@ require 'json'
3
3
  require 'digest/md5'
4
4
 
5
5
  module DeathByCaptcha
6
-
6
+
7
7
  #
8
8
  # DeathByCaptcha HTTP API client
9
9
  #
10
10
  class HTTPClient < DeathByCaptcha::Client
11
-
11
+
12
12
  def get_user
13
13
  call('user', userpwd)
14
14
  end
15
-
15
+
16
16
  def get_captcha(cid)
17
17
  call("captcha/#{cid}")
18
18
  end
@@ -20,79 +20,79 @@ module DeathByCaptcha
20
20
  def report(cid)
21
21
  call("captcha/#{cid}/report", userpwd)['is_correct']
22
22
  end
23
-
23
+
24
24
  def remove(cid)
25
25
  not call("captcha/#{cid}/remove", userpwd)['captcha']
26
26
  end
27
-
27
+
28
28
  #
29
29
  # Protected methods.
30
30
  #
31
31
  protected
32
-
32
+
33
33
  def upload(captcha, options = {})
34
34
  options = {
35
- :is_case_sensitive => false,
36
- :is_raw_content => false
35
+ :is_case_sensitive => false,
36
+ :is_raw_content => false
37
37
  }.merge(options)
38
-
39
- data = userpwd
40
- data[:swid] = config.software_vendor_id
41
- data[:is_case_sensitive] = options[:is_case_sensitive] ? 1 : 0
42
- data[:captchafile] = load_file(captcha, options[:is_raw_content])
43
- response = call('captcha', data)
44
-
38
+
39
+ data = userpwd
40
+ data[:swid] = config.software_vendor_id
41
+ data[:is_case_sensitive] = (options[:is_case_sensitive] ? 1 : 0)
42
+ data[:captchafile] = load_file(captcha, options[:is_raw_content])
43
+ response = call('captcha', data)
44
+
45
45
  return response if response['captcha']
46
46
  end
47
-
47
+
48
48
  #
49
49
  # Private methods.
50
50
  #
51
51
  private
52
-
52
+
53
53
  def call(cmd, payload = {}, headers = {})
54
-
55
- headers = {} unless headers.is_a?(Hash)
56
- headers['Accept'] = config.http_response_type if headers['Accept'].nil?
54
+
55
+ headers = {} unless headers.is_a?(Hash)
56
+ headers['Accept'] = config.http_response_type if headers['Accept'].nil?
57
57
  headers['User-Agent'] = config.api_version if headers['User-Agent'].nil?
58
-
58
+
59
59
  log('SEND', "#{cmd} #{payload}")
60
-
60
+
61
61
  begin
62
62
  url = "#{config.http_base_url}/#{cmd}"
63
-
63
+
64
64
  if payload.empty?
65
65
  response = RestClient.get(url, headers)
66
66
  else
67
67
  response = RestClient.post(url, payload, headers)
68
68
  end
69
-
69
+
70
70
  log('RECV', "#{response.size} #{response}")
71
-
71
+
72
72
  return JSON.load(response)
73
-
73
+
74
74
  rescue RestClient::Unauthorized => exc
75
75
  raise DeathByCaptcha::Errors::AccessDenied
76
-
76
+
77
77
  rescue RestClient::RequestFailed => exc
78
- raise DeathByCaptcha::Errors::AccessDenied
79
-
78
+ raise DeathByCaptcha::Errors::CallError
79
+
80
80
  rescue RestClient::ServiceUnavailable => exc
81
81
  raise DeathByCaptcha::Errors::ServiceOverload
82
-
82
+
83
83
  else
84
84
  raise DeathByCaptcha::Errors::CallError
85
-
85
+
86
86
  end
87
-
87
+
88
88
  return {}
89
-
89
+
90
90
  end
91
-
91
+
92
92
  end
93
-
93
+
94
94
  def self.http_client(username, password, extra = {})
95
95
  DeathByCaptcha::HTTPClient.new(username, password, extra)
96
96
  end
97
-
97
+
98
98
  end
@@ -5,109 +5,93 @@ require 'socket'
5
5
  require 'base64'
6
6
 
7
7
  module DeathByCaptcha
8
-
8
+
9
9
  #
10
10
  # DeathByCaptcha Socket API client
11
11
  #
12
12
  class SocketClient < DeathByCaptcha::Client
13
-
14
- #
15
- # Socket API server's host & ports range.
16
- #
17
- @@socket_host = 'api.deathbycaptcha.com'
18
- @@socket_ports = (8123...8131).to_a
19
-
13
+
20
14
  def initialize(username, password, extra = {})
21
- @mutex = Mutex.new
15
+ @mutex = Mutex.new
22
16
  @socket = nil
23
-
17
+
24
18
  super(username, password, extra)
25
19
  end
26
-
20
+
27
21
  def get_user
28
22
  call('user')
29
23
  end
30
-
24
+
31
25
  def get_captcha(cid)
32
- call('captcha', {:captcha => cid})
26
+ call('captcha', { :captcha => cid })
33
27
  end
34
28
 
35
29
  def report(cid)
36
- data = { 'captcha' => cid }
37
- call('report', data)[:is_correct]
30
+ call('report', { :captcha => cid })[:is_correct]
38
31
  end
39
-
32
+
40
33
  #
41
34
  # Protected methods.
42
35
  #
43
36
  protected
44
-
37
+
45
38
  def upload(captcha, is_case_sensitive = false, is_raw_content = false)
46
39
  data = {
47
- :captcha => Base64.encode64(load_file(captcha, is_raw_content).read),
48
- :is_case_sensitive => (is_case_sensitive ? 1 : 0)
40
+ :captcha => Base64.encode64(load_file(captcha, is_raw_content).read),
41
+ :is_case_sensitive => (is_case_sensitive ? 1 : 0)
49
42
  }
50
-
43
+
51
44
  call('upload', data)
52
45
  end
53
-
46
+
54
47
  #
55
48
  # Private methods.
56
49
  #
57
50
  private
58
-
51
+
59
52
  def connect
60
53
  unless @socket
61
54
  log('CONN')
62
-
63
55
  begin
64
- random_port = @@socket_ports[rand(@@socket_ports.size)]
65
-
56
+ random_port = config.socket_ports[rand(config.socket_ports.size)]
66
57
  # Creates a new Socket.
67
- addr = Socket.pack_sockaddr_in(random_port, @@socket_host)
68
-
69
- @socket = Socket.new(:INET, :STREAM)
58
+ addr = Socket.pack_sockaddr_in(random_port, config.socket_host)
59
+
60
+ @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
70
61
  @socket.connect_nonblock(addr)
62
+ rescue Errno::EINPROGRESS
63
+ log("INPROG", 'Waiting...')
71
64
  rescue Exception => e
72
- if e.errno == 36 # EINPROGRESS
73
- # Nothing.
74
- else
75
- close # Closes the socket.
76
- log('CONN', 'Could not connect.')
77
- log('CONN', e.backtrace.join('\n'))
78
-
79
- raise e
80
- end
65
+ close # Closes the socket.
66
+ log('CONN', 'Could not connect.')
67
+ log('CONN', e.backtrace.join("\n"))
68
+ raise e
81
69
  end
82
-
83
70
  end
84
-
85
71
  @socket
86
72
  end
87
-
73
+
88
74
  def close
89
75
  if @socket
90
76
  log('CLOSE')
91
-
92
77
  begin
93
78
  @socket.close
94
79
  rescue Exception => e
95
80
  log('CLOSE', 'Could not close socket.')
96
- log('CLOSE', e.backtrace.join('\n'))
81
+ log('CLOSE', e.backtrace.join("\n"))
97
82
  ensure
98
83
  @socket = nil
99
84
  end
100
85
  end
101
86
  end
102
-
87
+
103
88
  def send(sock, buf)
104
89
  # buf += '\n'
105
90
  fds = [sock]
106
-
107
91
  deadline = Time.now.to_f + 3 * config.polls_interval
108
92
  while deadline > Time.now.to_f and not buf.empty? do
109
93
  _, wr, ex = IO.select([], fds, fds, config.polls_interval)
110
-
94
+
111
95
  if ex and ex.any?
112
96
  raise IOError.new('send(): select() excepted')
113
97
  elsif wr
@@ -116,7 +100,7 @@ module DeathByCaptcha
116
100
  sent = wr.first.send(buf, 0)
117
101
  buf = buf[sent, buf.size - sent]
118
102
  rescue Exception => e
119
- if [35, 36].include? e.errno
103
+ if [35, 36].include? e.errno
120
104
  break
121
105
  else
122
106
  raise e
@@ -125,28 +109,29 @@ module DeathByCaptcha
125
109
  end
126
110
  end
127
111
  end
128
-
112
+
129
113
  unless buf.empty?
130
114
  raise IOError.new('send() timed out')
131
115
  else
132
116
  return self
133
117
  end
134
118
  end
135
-
119
+
136
120
  def recv(sock)
137
121
  fds = [sock]
138
122
  buf = ''
139
-
123
+
140
124
  deadline = Time.now.to_f() + 3 * config.polls_interval
141
125
  while deadline > Time.now.to_f do
142
126
  rd, _, ex = IO.select(fds, [], fds, config.polls_interval)
143
-
144
127
  if ex and ex.any?
145
128
  raise IOError.new('send(): select() excepted')
146
129
  elsif rd
147
130
  while true do
148
131
  begin
149
132
  s = rd.first.recv_nonblock(256)
133
+ rescue Errno::EAGAIN
134
+ break
150
135
  rescue Exception => e
151
136
  if [35, 36].include? e.errno
152
137
  break
@@ -161,41 +146,40 @@ module DeathByCaptcha
161
146
  end
162
147
  end
163
148
  end
164
-
165
149
  break if buf.size > 0
166
150
  end
167
151
  end
168
-
152
+
169
153
  return buf[0, buf.size] if buf.size > 0
170
154
  raise IOError.new('recv() timed out')
171
155
  end
172
-
156
+
173
157
  def call(cmd, data = {})
174
158
  data = {} if data.nil?
175
159
  data.merge!({ :cmd => cmd, :version => config.api_version })
176
-
160
+
177
161
  request = data.to_json
178
162
  log('SEND', request.to_s)
179
-
163
+
180
164
  response = nil
181
-
165
+
182
166
  (0...1).each do
183
167
  if not @socket and cmd != 'login'
184
168
  call('login', userpwd)
185
169
  end
186
-
170
+
187
171
  # Locks other threads.
188
172
  # If another thread has already acquired the lock, this thread will be locked.
189
173
  @mutex.lock
190
-
174
+
191
175
  begin
192
176
  sock = connect
193
177
  send(sock, request)
194
-
178
+
195
179
  response = recv(sock)
196
180
  rescue Exception => e
197
181
  log('SEND', e.message)
198
- log('SEND', e.backtrace.join('\n'))
182
+ log('SEND', e.backtrace.join("\n"))
199
183
  close
200
184
  else
201
185
  # If no exception raised.
@@ -203,24 +187,24 @@ module DeathByCaptcha
203
187
  ensure
204
188
  @mutex.unlock
205
189
  end
206
-
190
+
207
191
  end
208
-
192
+
209
193
  if response.nil?
210
194
  msg = 'Connection timed out during API request'
211
195
  log('SEND', msg)
212
-
196
+
213
197
  raise Exception.new(msg)
214
198
  end
215
-
199
+
216
200
  log('RECV', response.to_s)
217
-
201
+
218
202
  begin
219
203
  response = JSON.load(response)
220
204
  rescue Exception => e
221
205
  raise Exception.new('Invalid API response')
222
206
  end
223
-
207
+
224
208
  if 0x00 < response['status'] and 0x10 > response['status']
225
209
  raise DeathByCaptcha::Errors::AccessDenied
226
210
  elsif 0xff == response['status']
@@ -228,13 +212,13 @@ module DeathByCaptcha
228
212
  else
229
213
  return response
230
214
  end
231
-
215
+
232
216
  end
233
-
217
+
234
218
  end
235
-
236
- def self.socket_client(username, password, extra={})
219
+
220
+ def self.socket_client(username, password, extra = {})
237
221
  DeathByCaptcha::SocketClient.new(username, password, extra)
238
222
  end
239
-
223
+
240
224
  end
@@ -1,4 +1,4 @@
1
1
  module DeathByCaptcha
2
- VERSION = "4.1.2"
3
- API_VERSION = "DBC/Ruby v4.1.0"
4
- end
2
+ VERSION = "4.1.3"
3
+ API_VERSION = "DBC/Ruby v4.1.2"
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.1.2
4
+ version: 4.1.3
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: 2012-07-02 00:00:00.000000000 -03:00
13
- default_executable:
12
+ date: 2012-12-27 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rest-client
17
- requirement: &2152235960 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ~>
@@ -22,10 +21,15 @@ dependencies:
22
21
  version: 1.6.1
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *2152235960
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.1
26
30
  - !ruby/object:Gem::Dependency
27
31
  name: json
28
- requirement: &2152235460 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
29
33
  none: false
30
34
  requirements:
31
35
  - - ! '>='
@@ -33,7 +37,12 @@ dependencies:
33
37
  version: 1.4.6
34
38
  type: :runtime
35
39
  prerelease: false
36
- version_requirements: *2152235460
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.4.6
37
46
  description: Ruby API for DeathByCaptcha (Captcha Solver as a Service)
38
47
  email:
39
48
  - tech@infosimples.com.br
@@ -50,11 +59,10 @@ files:
50
59
  - lib/deathbycaptcha.rb
51
60
  - lib/deathbycaptcha/client.rb
52
61
  - lib/deathbycaptcha/config.rb
53
- - lib/deathbycaptcha/error.rb
62
+ - lib/deathbycaptcha/errors.rb
54
63
  - lib/deathbycaptcha/http_client.rb
55
64
  - lib/deathbycaptcha/socket_client.rb
56
65
  - lib/deathbycaptcha/version.rb
57
- has_rdoc: true
58
66
  homepage: http://www.infosimples.com.br/en/open-source/captcha-solving-api/
59
67
  licenses: []
60
68
  post_install_message:
@@ -75,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
83
  version: '0'
76
84
  requirements: []
77
85
  rubyforge_project: deathbycaptcha
78
- rubygems_version: 1.6.2
86
+ rubygems_version: 1.8.24
79
87
  signing_key:
80
88
  specification_version: 3
81
89
  summary: Ruby API for DeathByCaptcha (Captcha Solver as a Service)