deathbycaptcha 5.0.2 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d578d0181a5e858098bc2329884daff5971f7bbd
4
- data.tar.gz: b2681b030c07099cc78cb52dfc4382c6015d64b6
3
+ metadata.gz: 98c633b9bb114866ddf802c7420e8c44d737dffd
4
+ data.tar.gz: f940fb9797a688edebe3b90da31dbff445c1a27a
5
5
  SHA512:
6
- metadata.gz: 1eaf72f64a8b7e83d4e7b6933d17d3d48ea14a890cae901c1aa1f3e9693f7bbdac4e85ad23ba075010714a166946668fb60cd8032aa4d3814a31cf228e80a66c
7
- data.tar.gz: 2628bb9faeba7ee4e1438d307d3a20357bb69f3b2195afbf804add2c9d1979f48ddbc719c6f01d084e38572c76ec03b7d623f56d96733eec784d96a5e056a327
6
+ metadata.gz: 8dcf6fe8b34118de125bb698ffeabab7297631cdd7e740a63269e408c76555068a91232814e4e6417b4a83a4fb7db5be911e8273cf2f2f07455be5bab0e74683
7
+ data.tar.gz: 8fe87517c20ad3bd5bb1a3181c81d2fb2ba02658b4eeadad6e600d2b872ac1136eba1737a163f5bd306f8ebf072f14611e249390a02bbcf3feaa7be22a7dc3de
data/README.md CHANGED
@@ -24,14 +24,12 @@ Or install it yourself as:
24
24
 
25
25
  $ gem install deathbycaptcha
26
26
 
27
-
28
27
  ## Usage
29
28
 
30
29
  1. **Create a client**
31
30
 
32
31
  ```ruby
33
32
  # Create a client (:socket and :http clients are available)
34
- #
35
33
  client = DeathByCaptcha.new('myusername', 'mypassword', :http)
36
34
  ```
37
35
 
@@ -44,7 +42,7 @@ Or install it yourself as:
44
42
  If the solution is not available, an empty captcha object will be returned.
45
43
 
46
44
  ```ruby
47
- captcha = client.decode(url: 'http://bit.ly/1xXZcKo')
45
+ captcha = client.decode!(url: 'http://bit.ly/1xXZcKo')
48
46
  captcha.text # Solution of the captcha
49
47
  captcha.id # Numeric ID of the captcha solved by DeathByCaptcha
50
48
  captcha.is_correct # true if the solution is correct
@@ -53,16 +51,17 @@ Or install it yourself as:
53
51
  You can also specify *path*, *file*, *raw* and *raw64* when decoding an image.
54
52
 
55
53
  ```ruby
56
- client.decode(path: 'path/to/my/captcha/file')
54
+ client.decode!(path: 'path/to/my/captcha/file')
57
55
 
58
- client.decode(file: File.open('path/to/my/captcha/file', 'rb'))
56
+ client.decode!(file: File.open('path/to/my/captcha/file', 'rb'))
59
57
 
60
- client.decode(raw: File.open('path/to/my/captcha/file', 'rb').read)
58
+ client.decode!(raw: File.open('path/to/my/captcha/file', 'rb').read)
61
59
 
62
- client.decode(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
60
+ client.decode!(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
63
61
  ```
64
62
 
65
- > Internally, the gem will always convert the image to raw64 (binary base64 encoded).
63
+ > Internally, the gem will always convert any image to raw64 (binary base64
64
+ encoded).
66
65
 
67
66
  3. **Retrieve a previously solved captcha**
68
67
 
@@ -97,6 +96,86 @@ Or install it yourself as:
97
96
  status.is_service_overloaded # true if DeathByCaptcha is overloaded/unresponsive
98
97
  ```
99
98
 
99
+ ## New reCAPTCHA
100
+
101
+ > It's currently available only with the :http client.
102
+
103
+ To solve captchas similar to
104
+ [reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736), you can use
105
+ both the DeathByCaptcha's **Coordinates API** or **Image Group API**.
106
+
107
+ Please, read the oficial documentation at
108
+ http://www.deathbycaptcha.com/user/api/newrecaptcha.
109
+
110
+ ### Using the Coordinates API
111
+
112
+ ```ruby
113
+ # Read above all the instructions on how to solve a captcha.
114
+ captcha = client.decode!(type: 2, url: 'http://bit.ly/1VCUuzk')
115
+ ```
116
+
117
+ You should specify arguments with *type = 2* and an image similar to a screenshot of
118
+ the captcha. See an example:
119
+
120
+ **Captcha (screenshot)**
121
+
122
+ > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
123
+
124
+ ![Example of a captcha based on image clicks](captchas/2.jpg)
125
+
126
+ The response will be an array containing coordinates (x, y) where the human
127
+ clicked to solve the captcha. For the captcha above it should look something
128
+ like:
129
+
130
+ ```ruby
131
+ # captcha.text
132
+ "[[30,143],[241,325]]"
133
+
134
+ # captcha.coordinates
135
+ [[30, 143], [241, 325]]
136
+ ```
137
+
138
+ ### Using the Image Group API
139
+
140
+ ```ruby
141
+ # Read above all the instructions on how to solve a captcha.
142
+ captcha = client.decode!(
143
+ type: 3,
144
+ url: 'http://bit.ly/1i1CIaB', # single image with the clickable grid
145
+ banner: { url: 'http://bit.ly/1JTG4T3' }, # the banner image
146
+ banner_text: 'Click all images with bananas' # the banner text
147
+ )
148
+ ```
149
+
150
+ You should specify arguments with *type = 3* and the decomposed captcha as seen in the
151
+ example below:
152
+
153
+ **Captcha: images grid**
154
+
155
+ > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
156
+
157
+ ![Example of a grid of a captcha based on image clicks](captchas/3-grid.jpg)
158
+
159
+ **Captcha: banner**
160
+
161
+ ![Example of a banner of a captcha based on image clicks](captchas/3-banner.jpg)
162
+
163
+ **Captcha: banner text**
164
+
165
+ > Click all images with bananas
166
+
167
+ The response will be an array containing the indexes for each image that should
168
+ be clicked counting from left to right. For the captcha above it should look
169
+ something like:
170
+
171
+ ```ruby
172
+ # captcha.text
173
+ "[1,9]"
174
+
175
+ # captcha.indexes
176
+ [1, 9]
177
+ ```
178
+
100
179
  ## Notes
101
180
 
102
181
  #### Thread-safety
@@ -121,7 +200,7 @@ firewall.
121
200
  #### Ruby dependencies
122
201
 
123
202
  DeathByCaptcha >= 5.0.0 don't require specific dependencies. That saves you
124
- memmory and avoid conflicts with other gems.
203
+ memory and avoid conflicts with other gems.
125
204
 
126
205
  #### Input image format
127
206
 
@@ -131,7 +210,7 @@ you already have this format available on your side, there's no need to do
131
210
  convertions before calling the API.
132
211
 
133
212
  > Our recomendation is to never convert your image format, unless needed. Let
134
- > the gem convert internally. It may save you resources (CPU, memmory and IO).
213
+ > the gem convert internally. It may save you resources (CPU, memory and IO).
135
214
 
136
215
  #### Versioning
137
216
 
@@ -156,6 +235,7 @@ This gem has been tested on the following versions of Ruby:
156
235
  # Maintainers
157
236
 
158
237
  * [Débora Setton Fernandes](http://github.com/deborasetton)
238
+ * [Marcelo Mita](http://github.com/marcelomita)
159
239
  * [Rafael Barbolo](http://github.com/barbolo)
160
240
  * [Rafael Ivan Garcia](http://github.com/rafaelivan)
161
241
 
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "deathbycaptcha"
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
Binary file
Binary file
Binary file
@@ -87,16 +87,17 @@ module DeathByCaptcha
87
87
  raw64 = load_captcha(options)
88
88
  raise DeathByCaptcha::InvalidCaptcha if raw64.to_s.empty?
89
89
 
90
- _captcha = self.upload(raw64)
91
- while _captcha.text.to_s.empty?
90
+ decoded_captcha = self.upload(options.merge(raw64: raw64))
91
+
92
+ while decoded_captcha.text.to_s.empty?
92
93
  sleep(self.polling)
93
- _captcha = self.captcha(_captcha.id)
94
+ decoded_captcha = self.captcha(decoded_captcha.id)
94
95
  raise DeathByCaptcha::Timeout if (Time.now - started_at) > self.timeout
95
96
  end
96
97
 
97
- raise DeathByCaptcha::IncorrectSolution if !_captcha.is_correct
98
+ raise DeathByCaptcha::IncorrectSolution if !decoded_captcha.is_correct
98
99
 
99
- _captcha
100
+ decoded_captcha
100
101
  end
101
102
 
102
103
  # Retrieve information from an uploaded captcha.
@@ -53,8 +53,20 @@ module DeathByCaptcha
53
53
  #
54
54
  # @return [DeathByCaptcha::Captcha] The captcha object (not solved yet).
55
55
  #
56
- def upload(raw64)
57
- response = perform('captcha', :post_multipart, captchafile: "base64:#{raw64}")
56
+ def upload(options = {})
57
+ payload = {}
58
+ payload[:captchafile] = "base64:#{options[:raw64]}"
59
+ payload[:type] = options[:type] if options[:type].to_i > 0
60
+
61
+ if options[:type].to_i == 3
62
+ banner64 = load_captcha(options[:banner])
63
+ raise DeathByCaptcha::InvalidCaptcha if banner64.to_s.empty?
64
+
65
+ payload[:banner] = "base64:#{banner64}"
66
+ payload[:banner_text] = options[:banner_text].to_s
67
+ end
68
+
69
+ response = perform('captcha', :post_multipart, payload)
58
70
  DeathByCaptcha::Captcha.new(response)
59
71
  end
60
72
 
@@ -84,7 +96,6 @@ module DeathByCaptcha
84
96
  boundary, body = prepare_multipart_data(payload)
85
97
  req.content_type = "multipart/form-data; boundary=#{boundary}"
86
98
  req.body = body
87
-
88
99
  else
89
100
  uri = URI("#{BASE_URL}/#{action}?#{URI.encode_www_form(payload)}")
90
101
  req = Net::HTTP::Get.new(uri.request_uri, headers)
@@ -54,8 +54,12 @@ module DeathByCaptcha
54
54
  #
55
55
  # @return [DeathByCaptcha::Captcha] The captcha object (not solved yet).
56
56
  #
57
- def upload(raw64)
58
- response = perform('upload', captcha: raw64)
57
+ def upload(options = {})
58
+ if options[:type] && options[:type].to_i != 1
59
+ # Socket client implementation currently supports only text captchas.
60
+ raise DeathByCaptcha::InvalidCaptcha
61
+ end
62
+ response = perform('upload', captcha: options[:raw64])
59
63
  DeathByCaptcha::Captcha.new(response)
60
64
  end
61
65
 
@@ -16,5 +16,13 @@ module DeathByCaptcha
16
16
  def captcha=(value)
17
17
  @captcha = value.to_i
18
18
  end
19
+
20
+ def parsed_text
21
+ JSON.parse(text)
22
+ rescue
23
+ []
24
+ end
25
+ alias_method :coordinates, :parsed_text
26
+ alias_method :indexes, :parsed_text
19
27
  end
20
28
  end
@@ -1,4 +1,4 @@
1
1
  module DeathByCaptcha
2
- VERSION = "5.0.2"
2
+ VERSION = "5.0.3"
3
3
  API_VERSION = "DBC/Ruby v#{VERSION}"
4
4
  end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ username = CREDENTIALS['username']
4
+ password = CREDENTIALS['password']
5
+ path2 = './captchas/2.jpg' # path of the captcha (Coordinates API)
6
+ path3_grid = './captchas/3-grid.jpg' # path of the grid (Image Group API)
7
+ path3_banner = './captchas/3-banner.jpg' # path of the grid (Image Group API)
8
+ banner_text3 = 'Click all images with bananas'
9
+
10
+ describe 'Solving an image based captcha' do
11
+ before(:all) { @client = DeathByCaptcha.new(username, password, :http) }
12
+
13
+ context 'Coordinates API' do
14
+ describe '#decode!' do
15
+ before(:all) { @captcha = @client.decode!(type: 2, path: path2) }
16
+ it { expect(@captcha).to be_a(DeathByCaptcha::Captcha) }
17
+ it { expect(@captcha.text).to match(/\A\[\[.*\]\]\Z/) }
18
+ it { expect(@captcha.coordinates).to be_a(Array) }
19
+ it { expect(@captcha.coordinates.size).to be > 0 }
20
+ it 'expect coordinates to be valid' do
21
+ @captcha.coordinates.each do |coordinate|
22
+ expect(coordinate).to be_a(Array)
23
+ expect(coordinate.size).to eq(2)
24
+ end
25
+ end
26
+ it { expect(@captcha.is_correct).to be true }
27
+ it { expect(@captcha.id).to be > 0 }
28
+ it { expect(@captcha.id).to eq(@captcha.captcha) }
29
+ end
30
+ end
31
+
32
+ context 'Image Group API' do
33
+ describe '#decode!' do
34
+ before(:all) do
35
+ @captcha = @client.decode!(
36
+ type: 3,
37
+ path: path3_grid,
38
+ banner: { path: path3_banner },
39
+ banner_text: banner_text3
40
+ )
41
+ end
42
+ it { expect(@captcha).to be_a(DeathByCaptcha::Captcha) }
43
+ it { expect(@captcha.text).to match(/\A\[.*\]\Z/) }
44
+ it { expect(@captcha.indexes).to be_a(Array) }
45
+ it { expect(@captcha.indexes.size).to be > 0 }
46
+ it 'expect indexes to be valid' do
47
+ @captcha.indexes.each do |index|
48
+ expect(index).to be_a(Numeric)
49
+ end
50
+ end
51
+ it { expect(@captcha.is_correct).to be true }
52
+ it { expect(@captcha.id).to be > 0 }
53
+ it { expect(@captcha.id).to eq(@captcha.captcha) }
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deathbycaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.2
4
+ version: 5.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Débora Setton Fernandes, Rafael Barbolo, Rafael Ivan Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-26 00:00:00.000000000 Z
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -55,7 +55,9 @@ dependencies:
55
55
  description: DeathByCaptcha allows you to solve captchas with manual labor
56
56
  email:
57
57
  - team@infosimples.com.br
58
- executables: []
58
+ executables:
59
+ - console
60
+ - setup
59
61
  extensions: []
60
62
  extra_rdoc_files: []
61
63
  files:
@@ -65,7 +67,12 @@ files:
65
67
  - LICENSE.txt
66
68
  - README.md
67
69
  - Rakefile
70
+ - bin/console
71
+ - bin/setup
68
72
  - captchas/1.png
73
+ - captchas/2.jpg
74
+ - captchas/3-banner.jpg
75
+ - captchas/3-grid.jpg
69
76
  - deathbycaptcha.gemspec
70
77
  - lib/deathbycaptcha.rb
71
78
  - lib/deathbycaptcha/client.rb
@@ -80,6 +87,7 @@ files:
80
87
  - lib/deathbycaptcha/version.rb
81
88
  - spec/credentials.yml.example
82
89
  - spec/lib/client_spec.rb
90
+ - spec/lib/image_captcha_spec.rb
83
91
  - spec/spec_helper.rb
84
92
  homepage: https://github.com/infosimples/deathbycaptcha
85
93
  licenses:
@@ -108,4 +116,5 @@ summary: Ruby API for DeathByCaptcha (Captcha Solver as a Service)
108
116
  test_files:
109
117
  - spec/credentials.yml.example
110
118
  - spec/lib/client_spec.rb
119
+ - spec/lib/image_captcha_spec.rb
111
120
  - spec/spec_helper.rb