class DeathByCaptcha::Client

DeathByCaptcha::Client is a common interface inherited by DBC clients like DeathByCaptcha::Client::HTTP and DeathByCaptcha::Client::Socket.

Attributes

hostname[RW]
password[RW]
polling[RW]
timeout[RW]
username[RW]

Public Class Methods

create(username, password, connection = :socket, options = {}) click to toggle source

Create a DeathByCaptcha API client

@param [String] username Username of the DeathByCaptcha account. @param [String] password Password of the DeathByCaptcha account. @param [Symbol] connection Connection type (:socket, :http) @param [Hash] options Options hash. @option options [Integer] :timeout (60) Seconds before giving up. @option options [Integer] :polling (5) Seconds for polling the solution.

@return [DeathByCaptcha::Client] A Socket or HTTP Client instance.

# File lib/deathbycaptcha/client.rb, line 28
def self.create(username, password, connection = :socket, options = {})
  case connection
  when :socket
    DeathByCaptcha::Client::Socket.new(username, password, options)
  when :http
    DeathByCaptcha::Client::HTTP.new(username, password, options)
  else
    raise DeathByCaptcha::InvalidClientConnection
  end
end
new(username, password, options = {}) click to toggle source

Create a DeathByCaptcha client.

@param [String] username Username of the DeathByCaptcha account. @param [String] password Password of the DeathByCaptcha account. @param [Hash] options Options hash. @option options [Integer] :timeout (60) Seconds before giving up. @option options [Integer] :polling (5) Seconds for polling the solution. @option options [String] :hostname ('api.dbcapi.me') Custom API hostname.

@return [DeathByCaptcha::Client] A Client instance.

# File lib/deathbycaptcha/client.rb, line 50
def initialize(username, password, options = {})
  self.username   = username
  self.password   = password
  self.timeout    = options[:timeout] || 60
  self.polling    = options[:polling] || 5
  self.hostname   = options[:hostname] || 'api.dbcapi.me'
end

Public Instance Methods

captcha(captcha_id) click to toggle source

Retrieve information from an uploaded captcha.

@param [Integer] captcha_id Numeric ID of the captcha.

@return [DeathByCaptcha::Captcha] The captcha object.

# File lib/deathbycaptcha/client.rb, line 115
def captcha(captcha_id)
  raise NotImplementedError
end
decode(options = {}) click to toggle source

Decode the text from an image (i.e. solve a captcha).

@param [Hash] options Options hash. @option options [String] :url URL of the image to be decoded. @option options [String] :path File path of the image to be decoded. @option options [File] :file File instance with image to be decoded. @option options [String] :raw Binary content of the image to be decoded. @option options [String] :raw64 Binary content encoded in base64 of the image to be decoded.

@return [DeathByCaptcha::Captcha] The captcha (with solution) or an empty hash if something goes wrong.

# File lib/deathbycaptcha/client.rb, line 69
def decode(options = {})
  decode!(options)
rescue DeathByCaptcha::Error
  DeathByCaptcha::Captcha.new
end
decode!(options = {}) click to toggle source

Decode the text from an image (i.e. solve a captcha).

@param [Hash] options Options hash. @option options [String] :url URL of the image to be decoded. @option options [String] :path File path of the image to be decoded. @option options [File] :file File instance with image to be decoded. @option options [String] :raw Binary content of the image to be decoded. @option options [String] :raw64 Binary content encoded in base64 of the image to be decoded.

@return [DeathByCaptcha::Captcha] The captcha (with solution if an error is not raised).

# File lib/deathbycaptcha/client.rb, line 86
def decode!(options = {})
  started_at = Time.now

  # don't load image data for Token API v2 & v3
  raw64 = nil
  unless [4, 5].include? options[:type]
    raw64 = load_captcha(options)
    raise DeathByCaptcha::InvalidCaptcha if raw64.to_s.empty?
  end

  decoded_captcha = self.upload(options.merge(raw64: raw64))

  while decoded_captcha.text.to_s.empty?
    sleep(self.polling)
    decoded_captcha = self.captcha(decoded_captcha.id)
    raise DeathByCaptcha::Timeout if (Time.now - started_at) > self.timeout
  end

  raise DeathByCaptcha::IncorrectSolution if !decoded_captcha.is_correct

  decoded_captcha
end
report!(captcha_id) click to toggle source

Report incorrectly solved captcha for refund.

@param [Integer] captcha_id Numeric ID of the captcha.

@return [DeathByCaptcha::Captcha] The captcha object.

# File lib/deathbycaptcha/client.rb, line 125
def report!(captcha_id)
  raise NotImplementedError
end
status() click to toggle source

Retrieve DeathByCaptcha server status.

@return [DeathByCaptcha::ServerStatus] The server status object.

# File lib/deathbycaptcha/client.rb, line 141
def status
  raise NotImplementedError
end
upload(raw64) click to toggle source

Upload a captcha to DeathByCaptcha.

This method will not return the solution. It's only useful if you want to implement your own “decode” function.

@return [DeathByCaptcha::Captcha] The captcha object (not solved yet).

# File lib/deathbycaptcha/client.rb, line 152
def upload(raw64)
  raise NotImplementedError
end
user() click to toggle source

Retrieve your user information (which has the current credit balance).

@return [DeathByCaptcha::User] The user object.

# File lib/deathbycaptcha/client.rb, line 133
def user
  raise NotImplementedError
end

Private Instance Methods

load_captcha(options) click to toggle source

Load a captcha raw content encoded in base64 from options.

@param [Hash] options Options hash. @option options [String] :url URL of the image to be decoded. @option options [String] :path File path of the image to be decoded. @option options [File] :file File instance with image to be decoded. @option options [String] :raw Binary content of the image to be decoded. @option options [String] :raw64 Binary content encoded in base64 of the image to be decoded.

@return [String] The binary image base64 encoded.

# File lib/deathbycaptcha/client.rb, line 169
def load_captcha(options)
  if options[:raw64]
    options[:raw64]
  elsif options[:raw]
    Base64.encode64(options[:raw])
  elsif options[:file]
    Base64.encode64(options[:file].read())
  elsif options[:path]
    Base64.encode64(File.open(options[:path], 'rb').read)
  elsif options[:url]
    Base64.encode64(open_url(options[:url]))
  else
    ''
  end
rescue
  ''
end
open_url(url) click to toggle source
# File lib/deathbycaptcha/client.rb, line 187
def open_url(url)
  uri = URI(url)

  http = Net::HTTP.new(uri.host, uri.port)

  if uri.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  res = http.get(uri.request_uri)

  if (redirect = res.header['location'])
    open_url(redirect)
  else
    res.body
  end
end