captched_to_death 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +4 -0
- data/DeathByCaptcha.txt +47 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +85 -0
- data/Rakefile +12 -0
- data/captched_to_death.gemspec +26 -0
- data/lib/captched_to_death/client.rb +132 -0
- data/lib/captched_to_death/server.rb +10 -0
- data/lib/captched_to_death/version.rb +3 -0
- data/lib/captched_to_death.rb +33 -0
- data/spec/client_spec.rb +79 -0
- data/spec/server_spec.rb +10 -0
- data/spec/spec_helper.rb +3 -0
- metadata +93 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/DeathByCaptcha.txt
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Hi Captcha Killers,
|
2
|
+
|
3
|
+
For security and stability reasons, we’ve decided to change our domain
|
4
|
+
name. The new domain name will be http://deathbycaptcha.eu. This
|
5
|
+
change will allow us to keep operating our service securely. Our
|
6
|
+
deathbycaptcha.com domain will close in April.
|
7
|
+
|
8
|
+
We’re also changing our API server domain. The API server domain is
|
9
|
+
the one used by your software to send CAPTCHAs to our service. There’s
|
10
|
+
a small minority of software that require you to manually input some
|
11
|
+
Host or API details. Please find below instructions on how to identify
|
12
|
+
if your software requires manual changes, and how to make changes to
|
13
|
+
the configuration if needed:
|
14
|
+
|
15
|
+
* For software that doesn’t have an API (or Host) URL settings textbox:
|
16
|
+
** Don’t do anything! We’ve already informed most software vendors
|
17
|
+
about the API update :)
|
18
|
+
|
19
|
+
*For Software that asks for the DeathByCaptcha HTTP API:
|
20
|
+
** host: http://api.dbcapi.me/api
|
21
|
+
|
22
|
+
* For software that uses the Decaptcher POST URL:
|
23
|
+
** host: http://api.dbcapi.me/decaptcher
|
24
|
+
|
25
|
+
* For all other software, scripts or tools:
|
26
|
+
** host: api.dbcapi.me
|
27
|
+
|
28
|
+
Please notice that these changes must to be in place by the first week
|
29
|
+
of April 2012 the latest.
|
30
|
+
|
31
|
+
Are you a software vendor and you haven’t heard anything from us? Send
|
32
|
+
us an email! All of our API Clients are updated with these new
|
33
|
+
settings.
|
34
|
+
|
35
|
+
We would like this information to be known only to our users and not
|
36
|
+
the rest of the internet. Please avoid sharing the new API details
|
37
|
+
publicly. We trust you guys!
|
38
|
+
|
39
|
+
On the other hand, we do encourage you to inform all of your fellow
|
40
|
+
captcha killers about our new website domain name:
|
41
|
+
http://deathbycaptcha.eu
|
42
|
+
|
43
|
+
Happy Captcha Killing,
|
44
|
+
Jose M
|
45
|
+
Death By Captcha
|
46
|
+
|
47
|
+
http://pastebin.com/ns9xKuqi
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Cristian R. Arroyo
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
= CaptchedToDeath
|
2
|
+
|
3
|
+
{<img src="https://travis-ci.org/vivaserver/captched_to_death.png" />}[https://travis-ci.org/vivaserver/captched_to_death]
|
4
|
+
{<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/vivaserver/captched_to_death]
|
5
|
+
|
6
|
+
CaptchedToDeath is a simple HTTP client for the DeathByCaptcha API written in Ruby. Note that while the DeathByCaptcha service supports both a HTTP API and a Sockets API, this library supports only the former.
|
7
|
+
|
8
|
+
By default, all successful CaptchedToDeath responses are JSON-formatted. This cannot be changed yet.
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
Some actions require a valid DeathByCaptcha user account credentials, name and password. Some requests to the API will be rejected if they're not provided. Note that also a CaptchedToDeath::NoCreditError exception will be raised if the account has no more credits left on it's balance.
|
13
|
+
|
14
|
+
=== CaptchedToDeath::Client
|
15
|
+
|
16
|
+
Initialization of the client can be done in many ways. Beginning with the simplest:
|
17
|
+
|
18
|
+
client = CaptchedToDeath::Client.new
|
19
|
+
|
20
|
+
Pass the user credentials if you want to decode some CAPTCHA challenges with the remaining credits on your balance.
|
21
|
+
|
22
|
+
client = CaptchedToDeath::Client.new('username','password')
|
23
|
+
|
24
|
+
Pass a block if you want to set the verbose option, that enables RestClient responses logging (only to STDOUT).
|
25
|
+
|
26
|
+
client = CaptchedToDeath::Client.new do |c|
|
27
|
+
c.username = 'username'
|
28
|
+
c.password = 'password'
|
29
|
+
c.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
=== Balance checking
|
33
|
+
|
34
|
+
With your client initialized using you account credentials, you can check your current balance like so:
|
35
|
+
|
36
|
+
client.balance
|
37
|
+
=> {"is_banned"=>false, "status"=>0, "rate"=>0.139, "balance"=>672.204, "user"=>99999}
|
38
|
+
|
39
|
+
Note that the "balance" in the response means your cents left.
|
40
|
+
|
41
|
+
=== CAPTCHA decoding
|
42
|
+
|
43
|
+
With your client initialized using you account credentials, you can decode a CAPTCHA challenge if you still have credits left on your account. To do do so, just pass the CAPTCHA image URL:
|
44
|
+
|
45
|
+
client.decode('http://i.imgur.com/iWlb4.png')
|
46
|
+
=> {"status"=>0, "captcha"=>36923242, "is_correct"=>true, "text"=>"jd472tfo"}
|
47
|
+
|
48
|
+
Note that only GIF, JPEG and PNG are supported as valid CAPTCHA challenges. Also, the response time depends on the current DeathByCaptcha server load.
|
49
|
+
|
50
|
+
=== CAPTCHA status checking
|
51
|
+
|
52
|
+
Once the challenge has already been accepted, it's status can be checked at any time using it's CAPTCHA ID.
|
53
|
+
|
54
|
+
client.captcha(36723349)
|
55
|
+
=> {"status"=>0, "captcha"=>36723349, "is_correct"=>true, "text"=>"jd472tfo"}
|
56
|
+
|
57
|
+
=== CAPTCHA reporting
|
58
|
+
|
59
|
+
If you think the result of the challenge decoding is not correct you can report it to get a refund. But mind that you have to report it within the hour of submitting it and that abusing this feature might get you banned.
|
60
|
+
|
61
|
+
client.report(36723349)
|
62
|
+
=> {"status"=>0, "captcha"=>36723349, "is_correct"=>false, "text"=>"jd472tfo"}
|
63
|
+
|
64
|
+
=== DeathByCaptcha server status checking
|
65
|
+
|
66
|
+
You can check the current status of the DeathByCaptcha server to find out the average decoding time at any particular moment. This time will directly affect the response time of any decoding you submit afterwards.
|
67
|
+
|
68
|
+
CaptchedToDeath::Server.status
|
69
|
+
=> {"status"=>0, "todays_accuracy"=>0.890402, "solved_in"=>13, "is_service_overloaded"=>false}
|
70
|
+
|
71
|
+
== Contributing
|
72
|
+
|
73
|
+
1. Fork it
|
74
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
75
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
76
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
77
|
+
5. Create new Pull Request
|
78
|
+
|
79
|
+
== License
|
80
|
+
|
81
|
+
CaptchedToDeath is released under the {MIT License}[http://www.opensource.org/licenses/MIT].
|
82
|
+
|
83
|
+
== Copyright
|
84
|
+
|
85
|
+
Copyright (c)2012 {Cristian R. Arroyo}[mailto:cristian.arroyo@vivaserver.com]
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
# ref: http://rpheath.com/posts/394-get-the-most-out-of-test-unit
|
5
|
+
# ref: http://stackoverflow.com/a/8395163
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << 'lib' << 'spec'
|
8
|
+
t.verbose = false
|
9
|
+
t.pattern = 'spec/*_spec.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :test
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "captched_to_death/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "captched_to_death"
|
7
|
+
s.version = CaptchedToDeath::VERSION
|
8
|
+
s.authors = ["Cristian R. Arroyo"]
|
9
|
+
s.email = ["cristian.arroyo@vivaserver.com"]
|
10
|
+
s.homepage = "https://github.com/vivaserver/captched_to_death"
|
11
|
+
s.summary = %q{A simple HTTP client to DeathByCaptcha API}
|
12
|
+
s.description = %q{A simple HTTP client to DeathByCaptcha API using just RestClient}
|
13
|
+
|
14
|
+
s.add_runtime_dependency 'rest-client', "~> 1.6"
|
15
|
+
s.add_development_dependency 'minitest'
|
16
|
+
s.add_development_dependency 'rake'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
# specify any dependencies here; for example:
|
24
|
+
# s.add_development_dependency "rspec"
|
25
|
+
# s.add_runtime_dependency "rest-client"
|
26
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module CaptchedToDeath
|
5
|
+
class Client
|
6
|
+
attr_writer :username, :password, :accept, :verbose
|
7
|
+
|
8
|
+
# Sensible defaults that can be overriden by configuration block:
|
9
|
+
#
|
10
|
+
# client = CaptchedToDeath::Client.new do |c|
|
11
|
+
# c.username = 'username'
|
12
|
+
# c.password = 'password'
|
13
|
+
# c.verbose = true
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# or just:
|
17
|
+
#
|
18
|
+
# client = CaptchedToDeath::Client.new('username','password')
|
19
|
+
#
|
20
|
+
def initialize(*credentials)
|
21
|
+
@accept = :json
|
22
|
+
@verbose = false
|
23
|
+
if credentials.size == 2
|
24
|
+
@username = credentials[0].to_s
|
25
|
+
@password = credentials[1].to_s
|
26
|
+
end
|
27
|
+
yield self if block_given?
|
28
|
+
|
29
|
+
RestClient.log = Logger.new(STDOUT) if @verbose
|
30
|
+
end
|
31
|
+
|
32
|
+
# User credit balance, includes account details.
|
33
|
+
#
|
34
|
+
def balance
|
35
|
+
fail RejectedError if empty_credentials?
|
36
|
+
response = RestClient.post "#{API_URI}/user", {:username => @username, :password => @password}, :accept => @accept
|
37
|
+
fail ServiceError unless response.code == 200
|
38
|
+
JSON.parse(response)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Polls for uploaded CAPTCHA status.
|
42
|
+
# You don't have to supply your Death by Captcha credentials this time.
|
43
|
+
# Please don't poll for a CAPTCHA status more than once in a couple of seconds.
|
44
|
+
# This is considered abusive and might get you banned.
|
45
|
+
#
|
46
|
+
def captcha(captcha_id)
|
47
|
+
response = RestClient.get "#{API_URI}/captcha/#{captcha_id}", {:accept => @accept}
|
48
|
+
JSON.parse(response)
|
49
|
+
rescue RestClient::Exception => e
|
50
|
+
case e.http_code
|
51
|
+
when 404
|
52
|
+
fail NotFound
|
53
|
+
#503 (Service Temporarily Unavailable) when our service is overloaded (usually around 3:00–6:00 PM EST)
|
54
|
+
when 503
|
55
|
+
# not sure 503 is ever sent, but retry if it is
|
56
|
+
sleep Server.status['solved_in']
|
57
|
+
retry
|
58
|
+
else
|
59
|
+
raise e
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Solving a CAPTCHA using Death by Captcha HTTP API requires performing at least two steps.
|
64
|
+
#
|
65
|
+
def decode(challenge_url, referer=nil, agent=nil)
|
66
|
+
fail RejectedError if empty_credentials?
|
67
|
+
|
68
|
+
response = RestClient.post "#{API_URI}/captcha", {
|
69
|
+
:username => @username,
|
70
|
+
:password => @password,
|
71
|
+
:captchafile => captcha_file(challenge_url,referer,agent)
|
72
|
+
}, :accept => @accept
|
73
|
+
resolved = JSON.parse(response)
|
74
|
+
begin
|
75
|
+
sleep Server.status['solved_in']
|
76
|
+
resolved = captcha(resolved['captcha'])
|
77
|
+
end while resolved['text'].empty?
|
78
|
+
resolved
|
79
|
+
rescue RestClient::Exception => e
|
80
|
+
case e.http_code
|
81
|
+
#303 (See Other) CAPTCHA successfully uploaded: Location HTTP header will point to the status page
|
82
|
+
when 303
|
83
|
+
# RestClient: for result code 303 the redirection will be followed and the request transformed into a get
|
84
|
+
# (...so it'll be returned as a 200)
|
85
|
+
#403 (Forbidden) credentials were rejected, or you don't have enough credits
|
86
|
+
when 403
|
87
|
+
# TODO: discrimate wrong credentials
|
88
|
+
fail NoCreditError
|
89
|
+
#400 (Bad Request) if your request was not following the specification or not a valid image
|
90
|
+
when 400
|
91
|
+
fail RejectedError
|
92
|
+
#500 (Internal Server Error)
|
93
|
+
#503 (Service Temporarily Unavailable) when our service is overloaded (usually around 3:00–6:00 PM EST)
|
94
|
+
when 500, 503
|
95
|
+
fail ServiceError, e.http_body
|
96
|
+
else
|
97
|
+
raise e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Reports incorrectly solved CAPTCHAs.
|
102
|
+
# If you think your CAPTCHA was solved incorrectly, report it to Death by Captcha to get your money back.
|
103
|
+
# You'll get refunded if the CAPTCHA was uploaded less than an hour ago.
|
104
|
+
#
|
105
|
+
def report(captcha_id)
|
106
|
+
fail RejectedError if empty_credentials?
|
107
|
+
|
108
|
+
response = RestClient.post "#{API_URI}/captcha/#{captcha_id}/report", {
|
109
|
+
:username => @username,
|
110
|
+
:password => @password,
|
111
|
+
}, :accept => @accept
|
112
|
+
|
113
|
+
JSON.parse(response)
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def captcha_file(challenge_url, referer, agent) #:nodoc:
|
119
|
+
file = RestClient.get challenge_url, {'Referer' => referer, 'User-Agent' => agent}
|
120
|
+
if file =~ TYPE_EXIF || file =~ TYPE_JFIF || file =~ TYPE_GIF || file =~ TYPE_PNG
|
121
|
+
'base64:'+Base64.encode64(file)
|
122
|
+
else
|
123
|
+
raise RejectedError
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def empty_credentials? #:nodoc:
|
128
|
+
return true if @username.to_s.empty? || @password.to_s.empty?
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rest_client'
|
5
|
+
|
6
|
+
module CaptchedToDeath
|
7
|
+
# The base URI for the new DeathByCaptcha API. See DeathByCaptcha.txt
|
8
|
+
API_URI = 'http://api.dbcapi.me/api'
|
9
|
+
|
10
|
+
# Exception for insufficient user credits
|
11
|
+
class NoCreditError < StandardError; end
|
12
|
+
|
13
|
+
# Exception for unexisting CAPTCHA on status retreiving
|
14
|
+
class NotFound < StandardError; end
|
15
|
+
|
16
|
+
# Exception for missing/wrong user credentials; invalid captcha challenge
|
17
|
+
class RejectedError < StandardError; end
|
18
|
+
|
19
|
+
# Exception for server overloaded outage
|
20
|
+
class ServiceError < StandardError; end
|
21
|
+
|
22
|
+
# RegExps stolen from http://github.com/dim/ruby-imagespec
|
23
|
+
# see related blog post at http://boonedocks.net/mike/archives/162-Determining-Image-File-Types-in-Ruby.html
|
24
|
+
#
|
25
|
+
TYPE_EXIF = /^\xff\xd8\xff\xe1(.*){2}Exif/
|
26
|
+
TYPE_JFIF = /^\xff\xd8\xff\xe0\x00\x10JFIF/
|
27
|
+
TYPE_GIF = /^GIF8/
|
28
|
+
TYPE_PNG = /^\x89PNG/
|
29
|
+
end
|
30
|
+
|
31
|
+
require "captched_to_death/client"
|
32
|
+
require "captched_to_death/server"
|
33
|
+
require "captched_to_death/version"
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'minitest/mock'
|
3
|
+
|
4
|
+
describe CaptchedToDeath::Client do
|
5
|
+
before do
|
6
|
+
@username = ENV['DECAPTCHER_USERNAME']
|
7
|
+
@password = ENV['DECAPTCHER_PASSWORD']
|
8
|
+
|
9
|
+
# some CAPTCHA challenges for testing purposes:
|
10
|
+
# http://i.imgur.com/vOj5f.jpg (jd472tFO)
|
11
|
+
# http://i.imgur.com/iWlb4.png
|
12
|
+
# http://i.imgur.com/LsbEV.gif
|
13
|
+
# http://i.imgur.com/9a1da.jpg (jFnq60dd)
|
14
|
+
# http://i.imgur.com/nRITM.jpg (ByKBPX9Z)
|
15
|
+
# http://i.imgur.com/mr3E0.jpg (6gOFiI01)
|
16
|
+
# http://i.imgur.com/uY3RN.jpg (gTKDrGtF)
|
17
|
+
@challenge = 'http://i.imgur.com/vOj5f.jpg'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'is the correct way of using mocks' do
|
21
|
+
client = MiniTest::Mock.new
|
22
|
+
response = {"captcha" => 123456789, "is_correct" => true, "text" => "jd472tFO"}
|
23
|
+
|
24
|
+
client.expect :captcha, response, [123456789]
|
25
|
+
client.captcha(123456789).must_equal response
|
26
|
+
assert client.verify
|
27
|
+
|
28
|
+
client.expect :decode, response, [@challenge]
|
29
|
+
client.decode(@challenge).must_equal response
|
30
|
+
assert client.verify
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'when checking balance' do
|
34
|
+
subject do
|
35
|
+
CaptchedToDeath::Client.new(@username,@password)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'responds with account details or does not work if missing API credentials' do
|
39
|
+
if @username && @password
|
40
|
+
balance = subject.balance
|
41
|
+
balance.must_be_instance_of Hash
|
42
|
+
balance.keys.must_equal ["is_banned", "status", "rate", "balance", "user"] # NOTE: "balance" float means Cents
|
43
|
+
refute balance["is_banned"]
|
44
|
+
else
|
45
|
+
proc { subject.balance }.must_raise CaptchedToDeath::RejectedError
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'when polling for uploaded CAPTCHA status' do
|
51
|
+
subject do
|
52
|
+
CaptchedToDeath::Client.new
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'raises custom exception on unexisting CAPTCHA id' do
|
56
|
+
proc { subject.captcha(:captcha_id) }.must_raise CaptchedToDeath::NotFound
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'when decoding challenges' do
|
61
|
+
subject do
|
62
|
+
CaptchedToDeath::Client.new
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not work if missing API credentials' do
|
66
|
+
proc { subject.decode(@challenge) }.must_raise CaptchedToDeath::RejectedError
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'when reporting wrongly resolved captchas' do
|
71
|
+
subject do
|
72
|
+
CaptchedToDeath::Client.new
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'does not work if missing API credentials' do
|
76
|
+
proc { subject.report(:captcha_id) }.must_raise CaptchedToDeath::RejectedError
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe CaptchedToDeath::Server do
|
4
|
+
it 'checks for remote server status' do
|
5
|
+
status = CaptchedToDeath::Server.status
|
6
|
+
status.must_be_instance_of Hash
|
7
|
+
status.keys.must_equal ["status", "todays_accuracy", "solved_in", "is_service_overloaded"]
|
8
|
+
# NOTE: status["solved_in"] integer means Seconds
|
9
|
+
end
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: captched_to_death
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cristian R. Arroyo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-19 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: &72562580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *72562580
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: minitest
|
27
|
+
requirement: &72562370 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *72562370
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &72562140 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *72562140
|
47
|
+
description: A simple HTTP client to DeathByCaptcha API using just RestClient
|
48
|
+
email:
|
49
|
+
- cristian.arroyo@vivaserver.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .travis.yml
|
56
|
+
- DeathByCaptcha.txt
|
57
|
+
- Gemfile
|
58
|
+
- LICENSE.txt
|
59
|
+
- README.rdoc
|
60
|
+
- Rakefile
|
61
|
+
- captched_to_death.gemspec
|
62
|
+
- lib/captched_to_death.rb
|
63
|
+
- lib/captched_to_death/client.rb
|
64
|
+
- lib/captched_to_death/server.rb
|
65
|
+
- lib/captched_to_death/version.rb
|
66
|
+
- spec/client_spec.rb
|
67
|
+
- spec/server_spec.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
homepage: https://github.com/vivaserver/captched_to_death
|
70
|
+
licenses: []
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.10
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: A simple HTTP client to DeathByCaptcha API
|
93
|
+
test_files: []
|