deathbycaptcha 4.1.2 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
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)