zero_captcha 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e8f70c4d1910b8d269b4f6ab284dac6b97c0ac7b
4
+ data.tar.gz: 515a4fcf417ad0b0f6dbf8463147d7aa2df71352
5
+ SHA512:
6
+ metadata.gz: 87822e89be4d7b0875be5f3ef09f8d44aa4751888ffce5bc65edbe69f794ef1cf4c2a24d9bb78d6275e6f934ad5c8612982ef5e6f77e1e4c8cf7b731d5f8c4f5
7
+ data.tar.gz: 8d2b43bb65f869c31ccb93d4f93a34c0cdb06f391fa9386022dfefcdc825aaffb872cfcd039d677e9112ebba9bc55e42a81e0247df506108da6e74c590ec3a48
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.ruby-version
11
+ /.ruby-gemset
12
+ /spec/credentials.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --order rand
@@ -0,0 +1,8 @@
1
+ ### Comming next
2
+
3
+ * ?
4
+
5
+ ### 1.0.0 - 2015-06-08
6
+
7
+ Initial version of ZeroCaptcha, a captcha solver service that is 100% software
8
+ powered and accessible through a private API (zerocaptcha at infosimples.com).
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zero_captcha.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Infosimples
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,140 @@
1
+ Developed by [Infosimples](https://infosimples.com), a brazilian company that
2
+ offers [data extraction solutions](https://infosimples.com/en/data-engineering)
3
+ and [Ruby on Rails development](https://infosimples.com/en/software-development).
4
+
5
+
6
+ # ZeroCaptcha
7
+
8
+ ZeroCaptcha is a Ruby API for an enterprise captcha solving service developed by
9
+ Infosimples that is 100% powered by artificial intelligence software.
10
+
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'zero_captcha', '~> 1.0.0'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install zero_captcha
27
+
28
+
29
+ ## Usage
30
+
31
+ 1. **Create a client**
32
+
33
+ ```ruby
34
+ # Create a client
35
+ #
36
+ client = ZeroCaptcha.new('mytoken')
37
+ ```
38
+
39
+ 2. **Solve a captcha**
40
+
41
+ There are two methods available: **decode** and **decode!**
42
+ * **decode** doesn't raise exceptions.
43
+ * **decode!** may raise a *ZeroCaptcha::Error* if something goes wrong.
44
+
45
+ If the solution is not available, an empty captcha object will be returned.
46
+
47
+ ```ruby
48
+ captcha = client.decode(url: 'http://bit.ly/1xXZcKo', solver: 'captcha-type-1')
49
+ captcha.text # Solution of the captcha
50
+ captcha.id # Numeric ID of the captcha solved by ZeroCaptcha
51
+ captcha.correct? # true if the solution is correct
52
+ captcha.duration # How long it took to solve the captcha in milliseconds.
53
+ ```
54
+
55
+ You can also specify *path*, *file*, *raw* and *raw64* when decoding an image.
56
+
57
+ ```ruby
58
+ client.decode(path: 'path/to/my/captcha/file', solver: 'captcha-type-1')
59
+
60
+ client.decode(file: File.open('path/to/my/captcha/file', 'rb'), solver: 'captcha-type-1')
61
+
62
+ client.decode(raw: File.open('path/to/my/captcha/file', 'rb').read, solver: 'captcha-type-1')
63
+
64
+ client.decode(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read), solver: 'captcha-type-1')
65
+ ```
66
+
67
+ > Internally, the gem will always convert the image to raw64 (binary base64 encoded).
68
+
69
+ 3. **Report incorrectly solved captcha for refund**
70
+
71
+ ```ruby
72
+ captcha = client.report_incorrect(130920620) # with 130920620 as the captcha id
73
+ ```
74
+
75
+ > ***Warning:*** *do not abuse on this method, otherwise you may get banned*
76
+
77
+ 4. **Report correctly solved captcha for statistics**
78
+
79
+ ```ruby
80
+ captcha = client.report_correct(130920620) # with 130920620 as the captcha id
81
+ ```
82
+
83
+ ## Notes
84
+
85
+ #### Thread-safety
86
+
87
+ The API is thread-safe, which means it is perfectly fine to share a client
88
+ instance between multiple threads.
89
+
90
+ #### Ruby dependencies
91
+
92
+ ZeroCaptcha don't require specific dependencies. That saves you memory and
93
+ avoid conflicts with other gems.
94
+
95
+ #### Input image format
96
+
97
+ Any format you use in the decode method (url, file, path, raw, raw64) will
98
+ always be converted to a raw64, which is a binary base64 encoded string. So, if
99
+ you already have this format available on your side, there's no need to do
100
+ convertions before calling the API.
101
+
102
+ > Our recomendation is to never convert your image format, unless needed. Let
103
+ > the gem convert internally. It may save you resources (CPU, memory and IO).
104
+
105
+ #### Versioning
106
+
107
+ ZeroCaptcha gem uses [Semantic Versioning](http://semver.org/).
108
+
109
+ #### Ruby versions
110
+
111
+ This gem has been tested with the following versions of Ruby:
112
+
113
+ * MRI 2.2.2
114
+ * MRI 2.2.0
115
+ * MRI 2.1.5
116
+ * MRI 2.0.0
117
+ * MRI 1.9.3
118
+
119
+ # Maintainers
120
+
121
+ * [Rafael Barbolo](http://github.com/barbolo)
122
+
123
+
124
+ ## Contributing
125
+
126
+ 1. Fork it ( https://github.com/infosimples/zero_captcha/fork )
127
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
128
+ 3. **Run/add tests (RSpec)**
129
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
130
+ 5. Push to the branch (`git push origin my-new-feature`)
131
+ 6. Create a new Pull Request
132
+ 7. Yay. Thanks for contributing :)
133
+
134
+ All contributors:
135
+ https://github.com/infosimples/zero_captcha/graphs/contributors
136
+
137
+
138
+ # License
139
+
140
+ MIT License. Copyright (C) 2011-2015 Infosimples. https://infosimples.com/
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "zero_captcha"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'net/http'
4
+
5
+ # The module ZeroCaptcha contains all the code for the zero_captcha gem.
6
+ # It acts as a safely namespace that isolates logic from ZeroCaptcha from any
7
+ # project that uses it.
8
+ #
9
+ module ZeroCaptcha
10
+ # Create a ZeroCaptcha API client. This is a shortcut to
11
+ # ZeroCaptcha::Client.new.
12
+ #
13
+ def self.new(*args)
14
+ ZeroCaptcha::Client.new(*args)
15
+ end
16
+
17
+ # Base class of a model object returned by ZeroCaptcha API.
18
+ #
19
+ class Model
20
+ def initialize(values = {})
21
+ values.each do |key, value|
22
+ send("#{key}=", value) if respond_to?("#{key}=")
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ require 'zero_captcha/client'
29
+ require 'zero_captcha/errors'
30
+ require 'zero_captcha/http'
31
+ require 'zero_captcha/models/captcha'
32
+ require 'zero_captcha/version'
@@ -0,0 +1,142 @@
1
+ module ZeroCaptcha
2
+ # ZeroCaptcha::Client is a client that communicates with the ZeroCaptcha API:
3
+ # https://zerocaptcha.infosimples.com/.
4
+ #
5
+ class Client
6
+ BASE_URL = 'https://zerocaptcha.infosimples.com/api/v1/captcha/:action.json'
7
+
8
+ attr_accessor :token, :timeout
9
+
10
+ # Create a ZeroCaptcha API client.
11
+ #
12
+ # @param [String] token Token of the ZeroCaptcha account.
13
+ # @param [Hash] options Options hash.
14
+ # @option options [Integer] :timeout (60) Seconds before giving up of a
15
+ # captcha being solved.
16
+ #
17
+ # @return [ZeroCaptcha::Client] A Client instance.
18
+ #
19
+ def initialize(token, options = {})
20
+ self.token = token
21
+ self.timeout = options[:timeout] || 60
22
+ end
23
+
24
+ # Decode the text from an image (i.e. solve a captcha).
25
+ #
26
+ # @param [Hash] options Options hash.
27
+ # @option options [String] :url URL of the image to be decoded.
28
+ # @option options [String] :path File path of the image to be decoded.
29
+ # @option options [File] :file File instance with image to be decoded.
30
+ # @option options [String] :raw Binary content of the image to be
31
+ # decoded.
32
+ # @option options [String] :raw64 Binary content encoded in base64 of the
33
+ # image to be decoded.
34
+ #
35
+ # @return [ZeroCaptcha::Captcha] The captcha (with solution) or an empty
36
+ # hash if something goes wrong.
37
+ #
38
+ def decode(options = {})
39
+ decode!(options)
40
+ rescue ZeroCaptcha::Error
41
+ ZeroCaptcha::Captcha.new
42
+ end
43
+
44
+ # Decode the text from an image (i.e. solve a captcha).
45
+ #
46
+ # @param [Hash] options Options hash.
47
+ # @option options [String] :url URL of the image to be decoded.
48
+ # @option options [String] :path File path of the image to be decoded.
49
+ # @option options [File] :file File instance with image to be decoded.
50
+ # @option options [String] :raw Binary content of the image to be
51
+ # decoded.
52
+ # @option options [String] :raw64 Binary content encoded in base64 of the
53
+ # image to be decoded.
54
+ #
55
+ # @return [ZeroCaptcha::Captcha] The captcha (with solution) if an error
56
+ # is not raised.
57
+ #
58
+ def decode!(options = {})
59
+ raw64 = load_captcha(options)
60
+ solver = options[:solver]
61
+
62
+ response = request(solver, :multipart, image64: raw64)
63
+ captcha = ZeroCaptcha::Captcha.new(response)
64
+
65
+ fail(ZeroCaptcha::IncorrectSolution) unless captcha.correct?
66
+
67
+ captcha
68
+ end
69
+
70
+ # Report incorrectly solved captcha for refund.
71
+ #
72
+ # @param [Integer] id Numeric ID of the captcha.
73
+ #
74
+ # @return [ZeroCaptcha::Captcha] The captcha with current "correct" value.
75
+ #
76
+ def report_incorrect(id)
77
+ response = request('report_incorrect', :post, id: id)
78
+ ZeroCaptcha::Captcha.new(response)
79
+ end
80
+
81
+ # Report correctly solved captcha for statistics.
82
+ #
83
+ # @param [Integer] id Numeric ID of the captcha.
84
+ #
85
+ # @return [ZeroCaptcha::Captcha] The captcha with current "correct" value.
86
+ #
87
+ def report_correct(id)
88
+ response = request('report_correct', :post, id: id)
89
+ ZeroCaptcha::Captcha.new(response)
90
+ end
91
+
92
+ private
93
+
94
+ # Load a captcha raw content encoded in base64 from options.
95
+ #
96
+ # @param [Hash] options Options hash.
97
+ # @option options [String] :url URL of the image to be decoded.
98
+ # @option options [String] :path File path of the image to be decoded.
99
+ # @option options [File] :file File instance with image to be decoded.
100
+ # @option options [String] :raw Binary content of the image to bedecoded.
101
+ # @option options [String] :raw64 Binary content encoded in base64 of the
102
+ # image to be decoded.
103
+ #
104
+ # @return [String] The binary image base64 encoded.
105
+ #
106
+ def load_captcha(options)
107
+ if options[:raw64]
108
+ options[:raw64]
109
+ elsif options[:raw]
110
+ Base64.encode64(options[:raw])
111
+ elsif options[:file]
112
+ Base64.encode64(options[:file].read)
113
+ elsif options[:path]
114
+ Base64.encode64(File.open(options[:path], 'rb').read)
115
+ elsif options[:url]
116
+ Base64.encode64(ZeroCaptcha::HTTP.open_url(options[:url]))
117
+ else
118
+ fail ZeroCaptcha::ArgumentError, 'Illegal image format'
119
+ end
120
+ rescue
121
+ raise ZeroCaptcha::InvalidCaptcha
122
+ end
123
+
124
+ # Perform an HTTP request to the ZeroCaptcha API.
125
+ #
126
+ # @param [String] action API method name.
127
+ # @param [Symbol] method HTTP method (:get, :post, :multipart).
128
+ # @param [Hash] payload Data to be sent through the HTTP request.
129
+ #
130
+ # @return [Hash] Response from the ZeroCaptcha API.
131
+ #
132
+ def request(action, method = :get, payload = {})
133
+ res = ZeroCaptcha::HTTP.request(
134
+ url: BASE_URL.gsub(':action', action),
135
+ timeout: timeout,
136
+ method: method,
137
+ payload: payload.merge(token: token)
138
+ )
139
+ JSON.parse(res)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,52 @@
1
+ module ZeroCaptcha
2
+ # This is the base DeathByCaptcha exception class. Rescue it if you want to
3
+ # catch any exception that might be raised.
4
+ #
5
+ class Error < Exception
6
+ end
7
+
8
+ class ArgumentError < Error
9
+ end
10
+
11
+ class InvalidCaptcha < Error
12
+ def initialize
13
+ super('The captcha is empty or invalid')
14
+ end
15
+ end
16
+
17
+ class InvalidCaptchaType < Error
18
+ def initialize
19
+ super('Captcha type is invalid or cannot be solved by ZeroCaptcha')
20
+ end
21
+ end
22
+
23
+ class Timeout < Error
24
+ def initialize
25
+ super('The captcha was not solved in the expected time')
26
+ end
27
+ end
28
+
29
+ class IncorrectSolution < Error
30
+ def initialize
31
+ super('The captcha could not be solved correctly')
32
+ end
33
+ end
34
+
35
+ class APIForbidden < Error
36
+ def initialize
37
+ super('Access denied, please check your credentials and/or balance')
38
+ end
39
+ end
40
+
41
+ class APIBadRequest < Error
42
+ def initialize
43
+ super('The Captcha was rejected, check if it\'s a valid image')
44
+ end
45
+ end
46
+
47
+ class APIResponseError < Error
48
+ def initialize(info)
49
+ super("Invalid API response: #{info}")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,119 @@
1
+ module ZeroCaptcha
2
+ # ZeroCaptcha::HTTP exposes common HTTP routines that can be used by the
3
+ # ZeroCaptcha API client.
4
+ #
5
+ class HTTP
6
+ # Retrieve the contents of a captcha URL supporting HTTPS and redirects.
7
+ #
8
+ # @param [String] url The captcha URL.
9
+ #
10
+ # @return [String] The contents of the captcha URL.
11
+ #
12
+ def self.open_url(url)
13
+ uri = URI(url)
14
+
15
+ http = Net::HTTP.new(uri.host, uri.port)
16
+
17
+ if uri.scheme == 'https'
18
+ http.use_ssl = true
19
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
20
+ end
21
+
22
+ res = http.get(uri.request_uri)
23
+
24
+ if (redirect = res.header['location'])
25
+ open_url(redirect)
26
+ else
27
+ res.body
28
+ end
29
+ end
30
+
31
+ # Perform an HTTP request with support to multipart requests.
32
+ #
33
+ # @param [Hash] options Options hash.
34
+ # @param options [String] url URL to be requested.
35
+ # @param options [Symbol] method HTTP method (:get, :post, :multipart).
36
+ # @param options [Hash] payload Data to be sent through the HTTP request.
37
+ # @param options [Integer] timeout HTTP open/read timeout in seconds.
38
+ #
39
+ # @return [String] Response body of the HTTP request.
40
+ #
41
+ def self.request(options = {})
42
+ uri = URI(options[:url])
43
+ method = options[:method] || :get
44
+ payload = options[:payload] || {}
45
+ timeout = options[:timeout] || 60
46
+ headers = { 'User-Agent' => ZeroCaptcha::USER_AGENT }
47
+
48
+ case method
49
+ when :get
50
+ uri.query = URI.encode_www_form(payload)
51
+ req = Net::HTTP::Get.new(uri.request_uri, headers)
52
+
53
+ when :post
54
+ req = Net::HTTP::Post.new(uri.request_uri, headers)
55
+ req.set_form_data(payload)
56
+
57
+ when :multipart
58
+ req = Net::HTTP::Post.new(uri.request_uri, headers)
59
+ boundary, body = prepare_multipart_data(payload)
60
+ req.content_type = "multipart/form-data; boundary=#{boundary}"
61
+ req.body = body
62
+
63
+ else
64
+ fail ZeroCaptcha::ArgumentError, "Illegal HTTP method (#{method})"
65
+ end
66
+
67
+ http = Net::HTTP.new(uri.hostname, uri.port)
68
+ http.use_ssl = true if (uri.scheme == 'https')
69
+ http.open_timeout = timeout
70
+ http.read_timeout = timeout
71
+ res = http.request(req)
72
+
73
+ case res
74
+ when Net::HTTPSuccess
75
+ res.body
76
+
77
+ when Net::HTTPBadRequest
78
+ fail ZeroCaptcha::APIBadRequest
79
+
80
+ when Net::HTTPUnauthorized, Net::HTTPForbidden
81
+ fail ZeroCaptcha::APIForbidden
82
+
83
+ when Net::HTTPNotFound
84
+ fail ZeroCaptcha::InvalidCaptchaType
85
+
86
+ when Net::HTTPGatewayTimeOut
87
+ fail ZeroCaptcha::Timeout
88
+
89
+ else
90
+ fail ZeroCaptcha::APIResponseError, res.body
91
+ end
92
+
93
+ rescue Net::OpenTimeout, Net::ReadTimeout
94
+ raise ZeroCaptcha::Timeout
95
+ end
96
+
97
+ # Prepare the multipart data to be sent via a :multipart request.
98
+ #
99
+ # @param [Hash] payload Data to be prepared via a multipart post.
100
+ #
101
+ # @return [String, String] Boundary and body for the multipart post.
102
+ #
103
+ def self.prepare_multipart_data(payload)
104
+ boundary = 'infosimples' + rand(1_000_000).to_s # a random unique string
105
+
106
+ content = []
107
+ payload.each do |param, value|
108
+ content << '--' + boundary
109
+ content << "Content-Disposition: form-data; name=\"#{param}\""
110
+ content << ''
111
+ content << value
112
+ end
113
+ content << '--' + boundary + '--'
114
+ content << ''
115
+
116
+ [boundary, content.join("\r\n")]
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,18 @@
1
+ module ZeroCaptcha
2
+ # Model of a Captcha returned by ZeroCaptcha API.
3
+ #
4
+ class Captcha < ZeroCaptcha::Model
5
+ attr_accessor :id, :text, :code, :correct, :duration_in_milliseconds,
6
+ :created_at, :created_at_not_parsed
7
+
8
+ alias_method :correct?, :correct
9
+ alias_method :duration, :duration_in_milliseconds
10
+
11
+ def created_at=(datetime)
12
+ self.created_at_not_parsed = datetime
13
+ @created_at = Time.parse(datetime)
14
+ rescue
15
+ datetime
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # Specify zero_captcha's gem version.
2
+ module ZeroCaptcha
3
+ VERSION = '1.0.0'
4
+ USER_AGENT = "ZeroCaptcha/Ruby v#{VERSION}"
5
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'zero_captcha/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'zero_captcha'
8
+ spec.version = ZeroCaptcha::VERSION
9
+ spec.authors = ['Rafael Barbolo', 'Rafael Ivan Garcia']
10
+ spec.email = ["zerocaptcha@infosimples.com"]
11
+
12
+ spec.summary = %q{Ruby API for ZeroCaptcha (Captcha Solver as a Service for the Enterprise)}
13
+ spec.description = %q{ZeroCaptcha allows companies to solve captchas with artificial intelligence software, which is faster than humans and very accurate}
14
+ spec.homepage = "https://github.com/infosimples/zero_captcha"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.9"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.1"
25
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zero_captcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Rafael Barbolo
8
+ - Rafael Ivan Garcia
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.9'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.9'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.1'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.1'
56
+ description: ZeroCaptcha allows companies to solve captchas with artificial intelligence
57
+ software, which is faster than humans and very accurate
58
+ email:
59
+ - zerocaptcha@infosimples.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - lib/zero_captcha.rb
74
+ - lib/zero_captcha/client.rb
75
+ - lib/zero_captcha/errors.rb
76
+ - lib/zero_captcha/http.rb
77
+ - lib/zero_captcha/models/captcha.rb
78
+ - lib/zero_captcha/version.rb
79
+ - zero_captcha.gemspec
80
+ homepage: https://github.com/infosimples/zero_captcha
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.8
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Ruby API for ZeroCaptcha (Captcha Solver as a Service for the Enterprise)
104
+ test_files: []