bank_scrap 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +17 -5
- data/bank_scrap.gemspec +3 -3
- data/lib/bank_scrap/bank.rb +26 -34
- data/lib/bank_scrap/banks/bbva.rb +10 -2
- data/lib/bank_scrap/banks/ing.rb +5 -1
- data/lib/bank_scrap/banks/ing_backup.rb +237 -0
- data/lib/bank_scrap/version.rb +1 -1
- metadata +18 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4680376ad7f26ae34f9cf4262fa04b98b5b466ea
|
4
|
+
data.tar.gz: 4be7fda00b5c1a410ffb602979d20894d3511f6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9debe3eadab0fa8a98e3d52640cf2d2a49348f92f6a5b0d2bb5b2a9555ca19d4e61559ea3b990f28bbdcef9ceda1bf36e259d540ffe4c1e23ef25ec7ce53c250
|
7
|
+
data.tar.gz: d314b783e5a962669d2717f1fa2d15568284e7c4e03195e8d32073296138f7325758d2d218aa492cbfff6fe1b0b47105b951a94d05f995ba2f7fc34bcb128e70
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# BankScrap
|
2
2
|
|
3
3
|
Ruby gem to extract balance and transactions from banks. You can use it either as command line tool or as a library.
|
4
4
|
|
@@ -23,7 +23,7 @@ There are two approaches to solve this problem:
|
|
23
23
|
- Web scraping on the bank's site.
|
24
24
|
- Reverse engineering the bank's mobile app to use the same API the app uses.
|
25
25
|
|
26
|
-
|
26
|
+
BankScrap uses both methods depending on the bank.
|
27
27
|
|
28
28
|
## Requirements
|
29
29
|
|
@@ -52,10 +52,22 @@ Or, if you're using Bundler, just add the following to your Gemfile:
|
|
52
52
|
### From terminal
|
53
53
|
Retrieve balance account
|
54
54
|
|
55
|
-
|
55
|
+
##### Bankinter
|
56
56
|
|
57
|
-
|
57
|
+
$ bank_scrap balance bankinter --user YOUR_BANKINTER_USER --password YOUR_BANKINTER_PASSWORD
|
58
58
|
|
59
|
+
##### BBVA
|
60
|
+
|
61
|
+
$ bank_scrap balance bbva --user YOUR_BBVA_USER --password YOUR_BBVA_PASSWORD
|
62
|
+
|
63
|
+
##### ING Direct
|
64
|
+
ING needs one more argument: your bithday.
|
65
|
+
|
66
|
+
$ bank_scrap balance ing --user YOUR_DNI --password YOUR_PASSWORD --extra=birthday:01/01/1980
|
67
|
+
|
68
|
+
Replace 01/01/1980 with your actual birthday.
|
69
|
+
|
70
|
+
---
|
59
71
|
If you don't want to pass your user and password everytime you can define them in your .bash_profile by adding:
|
60
72
|
|
61
73
|
export BANK_SCRAP_USER=YOUR_BANK_USER
|
@@ -63,7 +75,7 @@ If you don't want to pass your user and password everytime you can define them i
|
|
63
75
|
|
64
76
|
### From Ruby code
|
65
77
|
|
66
|
-
You can also use this gem from your own app as library. To do so first you must initialize a
|
78
|
+
You can also use this gem from your own app as library. To do so first you must initialize a BankScrap::Bank object
|
67
79
|
|
68
80
|
```ruby
|
69
81
|
require 'bank_scrap'
|
data/bank_scrap.gemspec
CHANGED
@@ -22,12 +22,12 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
24
24
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
-
spec.add_development_dependency 'byebug', '~> 3.5.1'
|
25
|
+
spec.add_development_dependency 'byebug', '~> 3.5', '>= 3.5.1'
|
26
26
|
|
27
27
|
spec.add_dependency 'thor', "~> 0.19"
|
28
28
|
spec.add_dependency 'nokogiri', "~> 1.6"
|
29
29
|
spec.add_dependency 'execjs', "~> 2.2"
|
30
|
-
spec.add_dependency '
|
30
|
+
spec.add_dependency 'mechanize', "~> 2.7.3"
|
31
31
|
spec.add_dependency 'activesupport', "~> 4.1"
|
32
|
-
spec.add_dependency 'rmagick',
|
32
|
+
spec.add_dependency 'rmagick', '~> 2.2', '>= 2.2.2'
|
33
33
|
end
|
data/lib/bank_scrap/bank.rb
CHANGED
@@ -1,66 +1,58 @@
|
|
1
|
-
require '
|
1
|
+
require 'mechanize'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
module BankScrap
|
4
5
|
class Bank
|
5
6
|
|
6
7
|
WEB_USER_AGENT = 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'
|
8
|
+
attr_accessor :headers
|
7
9
|
|
8
10
|
private
|
9
11
|
|
10
12
|
def get(url)
|
11
|
-
@
|
12
|
-
@curl.get
|
13
|
-
|
14
|
-
@curl.body_str
|
13
|
+
@http.get(url).body
|
15
14
|
end
|
16
15
|
|
17
16
|
def post(url, fields)
|
18
|
-
@
|
19
|
-
|
20
|
-
# If hash, transform to Curl::PostField objects
|
21
|
-
if fields.is_a? Hash
|
22
|
-
fields = fields.collect {|key, value| Curl::PostField.content(key, value)}
|
23
|
-
end
|
24
|
-
|
25
|
-
@curl.post(fields)
|
26
|
-
@curl.body_str
|
17
|
+
@http.post(url, fields, @headers).body
|
27
18
|
end
|
28
19
|
|
29
20
|
def put(url, fields)
|
30
|
-
@
|
31
|
-
|
32
|
-
@curl.put(fields)
|
33
|
-
@curl.body_str
|
21
|
+
@http.put(url, fields, @headers).body
|
34
22
|
end
|
35
23
|
|
36
|
-
|
37
|
-
|
24
|
+
# Sets temporary HTTP headers, execute a code block
|
25
|
+
# and resets the headers
|
26
|
+
def with_headers(tmp_headers)
|
27
|
+
current_headers = @headers
|
28
|
+
set_headers(tmp_headers)
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
set_headers(current_headers)
|
38
32
|
end
|
39
33
|
|
34
|
+
|
40
35
|
def set_headers(headers)
|
41
|
-
headers.
|
36
|
+
@headers.merge! headers
|
37
|
+
@http.request_headers = @headers
|
42
38
|
end
|
43
39
|
|
44
|
-
def get_headers
|
45
|
-
@curl.header_str
|
46
|
-
end
|
47
40
|
|
48
41
|
def initialize_cookie(url)
|
49
42
|
log 'Initialize cookie'
|
50
43
|
|
51
|
-
@
|
52
|
-
@
|
53
|
-
|
54
|
-
@curl.body_str
|
44
|
+
@http.url = url
|
45
|
+
@http.get(url).body
|
55
46
|
end
|
56
47
|
|
57
48
|
def initialize_connection
|
58
|
-
@
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
49
|
+
@http = Mechanize.new do |mechanize|
|
50
|
+
mechanize.user_agent = WEB_USER_AGENT
|
51
|
+
mechanize.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
52
|
+
mechanize.log = Logger.new(STDOUT) if @debug
|
53
|
+
end
|
54
|
+
|
55
|
+
@headers = {}
|
64
56
|
end
|
65
57
|
|
66
58
|
def log(msg)
|
@@ -5,7 +5,8 @@ module BankScrap
|
|
5
5
|
BASE_ENDPOINT = 'https://bancamovil.grupobbva.com'
|
6
6
|
LOGIN_ENDPOINT = '/DFAUTH/slod/DFServletXML'
|
7
7
|
BALANCE_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/products/v1'
|
8
|
-
|
8
|
+
# BBVA expects an identifier before the actual User Agent, but 12345 works fine
|
9
|
+
USER_AGENT = '12345;Android;LGE;Nexus 5;1080x1776;Android;4.4.4;BMES;4.0.4'
|
9
10
|
|
10
11
|
def initialize(user, password, log: false, debug: false, extra_args: nil)
|
11
12
|
@user = format_user(user.dup)
|
@@ -24,6 +25,7 @@ module BankScrap
|
|
24
25
|
'Accept-Charset' => 'UTF-8',
|
25
26
|
'Connection' => 'Keep-Alive',
|
26
27
|
'Host' => 'bancamovil.grupobbva.com',
|
28
|
+
'Cookie2' => '$Version=1'
|
27
29
|
})
|
28
30
|
|
29
31
|
login
|
@@ -31,7 +33,13 @@ module BankScrap
|
|
31
33
|
|
32
34
|
def get_balance
|
33
35
|
log 'get_balance'
|
34
|
-
|
36
|
+
|
37
|
+
# Even if the required method is an HTTP POST
|
38
|
+
# the API requires a funny header that says is a GET
|
39
|
+
# otherwise the request doesn't work.
|
40
|
+
response = with_headers({'BBVA-Method' => 'GET'}) do
|
41
|
+
post(BASE_ENDPOINT + BALANCE_ENDPOINT, {})
|
42
|
+
end
|
35
43
|
|
36
44
|
json = JSON.parse(response)
|
37
45
|
json["balances"]["personalAccounts"]
|
data/lib/bank_scrap/banks/ing.rb
CHANGED
@@ -37,6 +37,10 @@ module BankScrap
|
|
37
37
|
balance
|
38
38
|
end
|
39
39
|
|
40
|
+
def raw_product_data
|
41
|
+
@data
|
42
|
+
end
|
43
|
+
|
40
44
|
private
|
41
45
|
|
42
46
|
def bundled_login
|
@@ -120,7 +124,7 @@ module BankScrap
|
|
120
124
|
0.upto(9) do |j|
|
121
125
|
pinpad_pixels_sample = single_number.get_pixels(0,0, SAMPLE_WIDTH, SAMPLE_HEIGHT)
|
122
126
|
|
123
|
-
img = Magick::ImageList.new("
|
127
|
+
img = Magick::ImageList.new(File.join(File.dirname(__FILE__), "/ing/numbers/pinpad#{j}.png")).first
|
124
128
|
number_pixels_sample = img.get_pixels(0, 0, SAMPLE_WIDTH, SAMPLE_HEIGHT)
|
125
129
|
diff = 0
|
126
130
|
pinpad_pixels_sample.each_with_index do |pixel, index|
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'execjs'
|
2
|
+
require 'pp'
|
3
|
+
require 'json'
|
4
|
+
require 'base64'
|
5
|
+
require 'RMagick'
|
6
|
+
require 'active_support'
|
7
|
+
require 'byebug'
|
8
|
+
require 'open-uri'
|
9
|
+
|
10
|
+
module BankScrap
|
11
|
+
class Ing < Bank
|
12
|
+
|
13
|
+
DESKTOP_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'
|
14
|
+
|
15
|
+
BASE_ENDPOINT = 'https://ing.ingdirect.es/'
|
16
|
+
FALSE_LOGIN_ENDPOINT = BASE_ENDPOINT + 'login/'
|
17
|
+
CACHE_ENDPOINT = BASE_ENDPOINT + 'login/cache.manifest'
|
18
|
+
DELETE_SESSION_ENDPOINT = BASE_ENDPOINT + 'genoma_api/rest/session'
|
19
|
+
LOGIN_ENDPOINT = BASE_ENDPOINT + 'genoma_login/rest/session'
|
20
|
+
POST_AUTH_ENDPOINT = BASE_ENDPOINT + 'genoma_api/login/auth/response'
|
21
|
+
CLIENT_ENDPOINT = BASE_ENDPOINT + 'genoma_api/rest/client'
|
22
|
+
PRODUCTS_ENDPOINT = BASE_ENDPOINT + 'genoma_api/rest/products'
|
23
|
+
|
24
|
+
SAMPLE_WIDTH = 30
|
25
|
+
SAMPLE_HEIGHT = 30
|
26
|
+
|
27
|
+
def initialize(dni, birthday, password, log: false, debug: false)
|
28
|
+
@dni = dni
|
29
|
+
@birthday = birthday
|
30
|
+
@password = password.to_s
|
31
|
+
@log = log
|
32
|
+
@debug = debug
|
33
|
+
|
34
|
+
initialize_connection
|
35
|
+
|
36
|
+
@curl.proxy_port = 8888
|
37
|
+
@curl.proxy_url = '192.168.1.21'
|
38
|
+
|
39
|
+
false_login
|
40
|
+
cache
|
41
|
+
delete_session
|
42
|
+
selected_positions = login
|
43
|
+
|
44
|
+
ticket = pass_pinpad(selected_positions)
|
45
|
+
|
46
|
+
post_auth(ticket)
|
47
|
+
call_client
|
48
|
+
|
49
|
+
get_products
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def false_login
|
55
|
+
@curl.url = FALSE_LOGIN_ENDPOINT
|
56
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
57
|
+
@curl.headers['Connection'] = 'keep-alive'
|
58
|
+
@curl.headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
|
59
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
60
|
+
@curl.headers['Accept-Language'] = 'en,es;q=0.8'
|
61
|
+
|
62
|
+
response = @curl.get
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache
|
66
|
+
@curl.url = CACHE_ENDPOINT
|
67
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
68
|
+
@curl.headers['Connection'] = 'keep-alive'
|
69
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
70
|
+
@curl.headers['Accept-Language'] = 'en,es;q=0.8'
|
71
|
+
end
|
72
|
+
|
73
|
+
def delete_session
|
74
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
75
|
+
@curl.headers['Connection'] = 'keep-alive'
|
76
|
+
@curl.headers['Pragma'] = 'no-cache'
|
77
|
+
@curl.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
|
78
|
+
@curl.headers['Origin'] = 'https://ing.ingdirect.es'
|
79
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
80
|
+
@curl.headers['Content-Type'] = 'application/json; charset=utf-8'
|
81
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/login/'
|
82
|
+
@curl.headers['Accept-Encoding'] = 'zip,deflate,sdch'
|
83
|
+
@curl.headers['Accept-Language'] = 'n,es;q=0.8'
|
84
|
+
@curl.headers['Cookie'] = 's_cc=true; s_mca=Direct; s_gts=1; s_nr=1414955726141; s_sq=%5B%5BB%5D%5D'
|
85
|
+
|
86
|
+
response = @curl.delete
|
87
|
+
pp response
|
88
|
+
end
|
89
|
+
|
90
|
+
def login
|
91
|
+
param = '{"loginDocument":{"documentType":0,"document":"' + @dni.to_s +
|
92
|
+
'"},"birthday":"' + @birthday.to_s + '","companyDocument":null,"device":"desktop"}'
|
93
|
+
puts param
|
94
|
+
@curl.url = LOGIN_ENDPOINT
|
95
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
96
|
+
@curl.headers['Connection'] = 'keep-alive'
|
97
|
+
@curl.headers['Pragma'] = 'no-cache'
|
98
|
+
|
99
|
+
@curl.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
|
100
|
+
@curl.headers['Origin'] = 'https://ing.ingdirect.es'
|
101
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
102
|
+
@curl.headers['Content-Type'] = 'application/json; charset=utf-8'
|
103
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/login/'
|
104
|
+
@curl.headers['Accept-Encoding'] = 'zip,deflate,sdch'
|
105
|
+
@curl.headers['Accept-Language'] = 'n,es;q=0.8'
|
106
|
+
@curl.headers['Cookie'] = 's_cc=true; s_mca=Direct; s_gts=1; s_nr=1414955726141; s_sq=%5B%5BB%5D%5D'
|
107
|
+
|
108
|
+
response = post(LOGIN_ENDPOINT, param)
|
109
|
+
# response = @curl.body_str
|
110
|
+
response = JSON.parse(response)
|
111
|
+
positions = response['pinPositions']
|
112
|
+
pinpad = response['pinpad']
|
113
|
+
|
114
|
+
save_pinpad_numbers(pinpad)
|
115
|
+
pinpad_numbers = recognize_pinpad_numbers
|
116
|
+
|
117
|
+
get_correct_positions(pinpad_numbers, positions)
|
118
|
+
end
|
119
|
+
|
120
|
+
def pass_pinpad(positions)
|
121
|
+
param = "{\"pinPositions\": #{positions}}"
|
122
|
+
@curl.url = LOGIN_ENDPOINT
|
123
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
124
|
+
@curl.headers['Connection'] = 'keep-alive'
|
125
|
+
@curl.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
|
126
|
+
@curl.headers['Origin'] = 'https://ing.ingdirect.es'
|
127
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
128
|
+
@curl.headers['Content-Type'] = 'application/json; charset=utf-8'
|
129
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/login/?clientId=281afde24c938607e5edeac6239e8a38&continue=%2Fpfm%2F'
|
130
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
131
|
+
|
132
|
+
response = put(LOGIN_ENDPOINT, param)
|
133
|
+
response = ActiveSupport::Gzip.decompress(response)
|
134
|
+
response = JSON.parse(response)
|
135
|
+
|
136
|
+
response['ticket']
|
137
|
+
end
|
138
|
+
|
139
|
+
def post_auth(ticket)
|
140
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
141
|
+
@curl.headers['Connection'] = 'keep-alive'
|
142
|
+
@curl.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
|
143
|
+
@curl.headers['Origin'] = 'https://ing.ingdirect.es'
|
144
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
145
|
+
@curl.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
|
146
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/login'
|
147
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate'
|
148
|
+
|
149
|
+
@curl.url = POST_AUTH_ENDPOINT
|
150
|
+
param = "ticket=#{ticket}&device=desktop"
|
151
|
+
@curl.post(param)
|
152
|
+
response = @curl.body_str
|
153
|
+
end
|
154
|
+
|
155
|
+
def call_client
|
156
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
157
|
+
@curl.headers['Connection'] = 'keep-alive'
|
158
|
+
@curl.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
|
159
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
160
|
+
@curl.headers['Content-Type'] = 'application/json; charset=utf-8'
|
161
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/pfm'
|
162
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
163
|
+
|
164
|
+
response = get(CLIENT_ENDPOINT)
|
165
|
+
|
166
|
+
response = ActiveSupport::Gzip.decompress(response)
|
167
|
+
response = JSON.parse(response)
|
168
|
+
end
|
169
|
+
|
170
|
+
def get_products
|
171
|
+
@curl.headers['Host'] = 'ing.ingdirect.es'
|
172
|
+
@curl.headers['Connection'] = 'keep-alive'
|
173
|
+
@curl.headers['Accept'] = '*/*'
|
174
|
+
@curl.headers['X-Requested-With'] = 'XMLHttpRequest'
|
175
|
+
@curl.headers['Content-Type'] = 'application/json; charset=utf-8'
|
176
|
+
@curl.headers['Referer'] = 'https://ing.ingdirect.es/pfm'
|
177
|
+
@curl.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
178
|
+
|
179
|
+
response = get(PRODUCTS_ENDPOINT)
|
180
|
+
|
181
|
+
File.open('response_raw.txt', 'w') { |file| file.write(response) }
|
182
|
+
response = ActiveSupport::Gzip.decompress(response)
|
183
|
+
File.open('response_decompressed.txt', 'w') { |file| file.write(response) }
|
184
|
+
File.open('response_parsed.txt', 'w') { |file| file.write(JSON.parse(response)) }
|
185
|
+
end
|
186
|
+
|
187
|
+
def save_pinpad_numbers(pinpad)
|
188
|
+
pinpad.each_with_index do |p,index|
|
189
|
+
File.open(build_tmp_path(index), 'wb'){ |f| f.write(Base64.decode64(p)) }
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def build_tmp_path(number)
|
194
|
+
"tmp/original_pinpad_#{number}.png"
|
195
|
+
end
|
196
|
+
|
197
|
+
def recognize_pinpad_numbers
|
198
|
+
pinpad_numbers = []
|
199
|
+
0.upto(9) do |i|
|
200
|
+
pinpad = Magick::ImageList.new(build_tmp_path(i)).first
|
201
|
+
|
202
|
+
differences = []
|
203
|
+
0.upto(9) do |j|
|
204
|
+
pinpad_pixels_sample = pinpad.get_pixels(0,0, SAMPLE_WIDTH, SAMPLE_HEIGHT)
|
205
|
+
|
206
|
+
img = Magick::ImageList.new("numbers/pinpad#{j}.png").first
|
207
|
+
number_pixels_sample = img.get_pixels(0, 0, SAMPLE_WIDTH, SAMPLE_HEIGHT)
|
208
|
+
diff = 0
|
209
|
+
pinpad_pixels_sample.each_with_index do |pixel, index|
|
210
|
+
sample_pixel = number_pixels_sample[index]
|
211
|
+
diff += (pixel.red - sample_pixel.red).abs +
|
212
|
+
(pixel.green - sample_pixel.green).abs +
|
213
|
+
(pixel.blue - sample_pixel.blue).abs
|
214
|
+
end
|
215
|
+
differences << diff
|
216
|
+
end
|
217
|
+
|
218
|
+
real_number = differences.each_with_index.min.last
|
219
|
+
pinpad_numbers << real_number
|
220
|
+
end
|
221
|
+
|
222
|
+
pinpad_numbers
|
223
|
+
end
|
224
|
+
|
225
|
+
def get_correct_positions(pinpad_numbers, positions)
|
226
|
+
first_digit = @password[positions[0] - 1]
|
227
|
+
second_digit = @password[positions[1] - 1]
|
228
|
+
third_digit = @password[positions[2] - 1]
|
229
|
+
|
230
|
+
[
|
231
|
+
pinpad_numbers.index(first_digit.to_i),
|
232
|
+
pinpad_numbers.index(second_digit.to_i),
|
233
|
+
pinpad_numbers.index(third_digit.to_i)
|
234
|
+
]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
data/lib/bank_scrap/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bank_scrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ismael Sánchez
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2015-01-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -46,6 +46,9 @@ dependencies:
|
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - "~>"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '3.5'
|
51
|
+
- - ">="
|
49
52
|
- !ruby/object:Gem::Version
|
50
53
|
version: 3.5.1
|
51
54
|
type: :development
|
@@ -53,6 +56,9 @@ dependencies:
|
|
53
56
|
version_requirements: !ruby/object:Gem::Requirement
|
54
57
|
requirements:
|
55
58
|
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.5'
|
61
|
+
- - ">="
|
56
62
|
- !ruby/object:Gem::Version
|
57
63
|
version: 3.5.1
|
58
64
|
- !ruby/object:Gem::Dependency
|
@@ -98,19 +104,19 @@ dependencies:
|
|
98
104
|
- !ruby/object:Gem::Version
|
99
105
|
version: '2.2'
|
100
106
|
- !ruby/object:Gem::Dependency
|
101
|
-
name:
|
107
|
+
name: mechanize
|
102
108
|
requirement: !ruby/object:Gem::Requirement
|
103
109
|
requirements:
|
104
110
|
- - "~>"
|
105
111
|
- !ruby/object:Gem::Version
|
106
|
-
version:
|
112
|
+
version: 2.7.3
|
107
113
|
type: :runtime
|
108
114
|
prerelease: false
|
109
115
|
version_requirements: !ruby/object:Gem::Requirement
|
110
116
|
requirements:
|
111
117
|
- - "~>"
|
112
118
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
119
|
+
version: 2.7.3
|
114
120
|
- !ruby/object:Gem::Dependency
|
115
121
|
name: activesupport
|
116
122
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,6 +136,9 @@ dependencies:
|
|
130
136
|
requirement: !ruby/object:Gem::Requirement
|
131
137
|
requirements:
|
132
138
|
- - "~>"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '2.2'
|
141
|
+
- - ">="
|
133
142
|
- !ruby/object:Gem::Version
|
134
143
|
version: 2.2.2
|
135
144
|
type: :runtime
|
@@ -137,6 +146,9 @@ dependencies:
|
|
137
146
|
version_requirements: !ruby/object:Gem::Requirement
|
138
147
|
requirements:
|
139
148
|
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '2.2'
|
151
|
+
- - ">="
|
140
152
|
- !ruby/object:Gem::Version
|
141
153
|
version: 2.2.2
|
142
154
|
description: Command line tools to get bank account details from some banks.
|
@@ -169,6 +181,7 @@ files:
|
|
169
181
|
- lib/bank_scrap/banks/ing/numbers/pinpad7.png
|
170
182
|
- lib/bank_scrap/banks/ing/numbers/pinpad8.png
|
171
183
|
- lib/bank_scrap/banks/ing/numbers/pinpad9.png
|
184
|
+
- lib/bank_scrap/banks/ing_backup.rb
|
172
185
|
- lib/bank_scrap/cli.rb
|
173
186
|
- lib/bank_scrap/version.rb
|
174
187
|
homepage: https://github.com/ismaGNU/bank_scrap
|
@@ -196,4 +209,3 @@ signing_key:
|
|
196
209
|
specification_version: 4
|
197
210
|
summary: Get your bank account details.
|
198
211
|
test_files: []
|
199
|
-
has_rdoc:
|