bankscrap-ing 2.0.1 → 2.0.2

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: 0d5fccc82101d67a0d768f91ecb55f7eb529efda
4
- data.tar.gz: d09de3829079e1f0a19cace24c988e9100b806f4
3
+ metadata.gz: ed4bde1de39bdad7eb256c46cb8e640e2cdc2649
4
+ data.tar.gz: 1cf85900279be718f5aa96e0eda0241d06e1acaf
5
5
  SHA512:
6
- metadata.gz: acde7258ac38668248a587cf1eb710414998d975b686ea48da8af444e474a8fa08eac95930e56b194851794c77a7ffec1ac3d3974c1025925bef8e1527ef0371
7
- data.tar.gz: 9b58b605e7283d547b8e8dd91a9b9f3f26b39b6be5bab347985a335f4af64d028ba9b44f841fe7d2a06b9faa8633ce717c20f61a70c42a3ff44c18170045485a
6
+ metadata.gz: ac715b32821ca8e47c66ca6a16d0fdb035bc52cf8c8808fbd45e51512ec7d4644830afd05bafc31870bb739fe8bc87f5c464e5c4a32c6f83bbb66e3dde6b7292
7
+ data.tar.gz: 5841c75e26529887bcdcf50882724594e817feae51df531bac51e003a4f8830c160572eb5dca19fb7ee44f3c2b190d26a0372eeac97ac9ec90ea8eacf66efe75
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # Bankscrap::ING
1
+ # 💸 Bankscrap::ING 💸
2
+
3
+ [![](http://188.166.39.57:3000/badge.svg)](http://188.166.39.57:3000)
4
+ [![Gem Version](https://badge.fury.io/rb/bankscrap-ing.svg)](https://badge.fury.io/rb/bankscrap-ing)
2
5
 
3
6
  Bankscrap adapter for the API behind ING's [mobile app](https://play.google.com/store/apps/details?id=www.ingdirect.nativeframe&hl=en).
4
7
  This adapter is only valid for personal accounts (the ones that work with that mobile APP), not for company accounts.
@@ -26,7 +29,7 @@ For usage instructions please read [Bankscrap readme](https://github.com/bankscr
26
29
 
27
30
  ## Contributing
28
31
 
29
- 1. Fork it ( https://github.com/bankscrap/bankscrap-ing/fork )
32
+ 1. [Fork it](https://github.com/bankscrap/bankscrap-ing/fork)
30
33
  2. Create your feature branch (`git checkout -b my-new-feature`)
31
34
  3. Commit your changes (`git commit -am 'Add some feature'`)
32
35
  4. Push to the branch (`git push origin my-new-feature`)
@@ -17,11 +17,9 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_runtime_dependency 'bankscrap', '~> 2.0.0'
21
- spec.add_runtime_dependency 'rmagick', '~> 2.2', '>= 2.2.2'
20
+ spec.add_runtime_dependency 'bankscrap', '~> 2.0.0'
21
+ spec.add_runtime_dependency 'levenshtein-ffi', '~> 1.1'
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 1.7'
24
- spec.add_development_dependency 'rake', '~> 10.0'
25
- spec.add_development_dependency 'byebug', '~> 8.2', '>= 8.2.5'
26
- spec.add_development_dependency 'rubocop', '~> 0.39.0'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
27
25
  end
@@ -2,25 +2,23 @@ require 'bankscrap'
2
2
 
3
3
  require 'json'
4
4
  require 'base64'
5
- require 'rmagick'
6
- require 'tempfile'
5
+ require 'zlib'
6
+ require 'levenshtein'
7
+
8
+ require_relative './config'
7
9
 
8
10
  module Bankscrap
9
11
  module ING
10
12
  class Bank < ::Bankscrap::Bank
11
- BASE_ENDPOINT = 'https://ing.ingdirect.es/'.freeze
12
- LOGIN_ENDPOINT = BASE_ENDPOINT + 'genoma_login/rest/session'
13
- POST_AUTH_ENDPOINT = BASE_ENDPOINT + 'genoma_api/login/auth/response'
14
- CLIENT_ENDPOINT = BASE_ENDPOINT + 'genoma_api/rest/client'
15
- PRODUCTS_ENDPOINT = BASE_ENDPOINT + 'genoma_api/rest/products'
16
-
17
- SAMPLE_WIDTH = 30
18
- SAMPLE_HEIGHT = 30
19
- SAMPLE_ROOT_PATH = '/numbers'.freeze
13
+ BASE_ENDPOINT = 'https://ing.ingdirect.es'.freeze
14
+ LOGIN_ENDPOINT = "#{BASE_ENDPOINT}/genoma_login/rest/session".freeze
15
+ POST_AUTH_ENDPOINT = "#{BASE_ENDPOINT}/genoma_api/login/auth/response".freeze
16
+ CLIENT_ENDPOINT = "#{BASE_ENDPOINT}/genoma_api/rest/client".freeze
17
+ PRODUCTS_ENDPOINT = "#{BASE_ENDPOINT}/genoma_api/rest/products".freeze
20
18
 
21
- REQUIRED_CREDENTIALS = [:dni, :password, :birthday]
19
+ REQUIRED_CREDENTIALS = %i(dni password birthday).freeze
22
20
 
23
- CURRENCY = Money::Currency.new("EUR")
21
+ CURRENCY = Money::Currency.new('EUR')
24
22
 
25
23
  def initialize(credentials = {})
26
24
  super do
@@ -68,15 +66,7 @@ module Bankscrap
68
66
  def fetch_transactions_for(account, start_date: Date.today - 1.month, end_date: Date.today)
69
67
  log "fetch_transactions for #{account.id}"
70
68
 
71
- # The API allows any limit to be passed, but we better keep
72
- # being good API citizens and make a loop with a short limit
73
- params = {
74
- fromDate: start_date.strftime('%d/%m/%Y'),
75
- toDate: end_date.strftime('%d/%m/%Y'),
76
- limit: 25,
77
- offset: 0
78
- }
79
-
69
+ params = build_transactions_request_params(start_date, end_date)
80
70
  transactions = []
81
71
  loop do
82
72
  request = get("#{PRODUCTS_ENDPOINT}/#{account.id}/movements", params: params)
@@ -84,27 +74,45 @@ module Bankscrap
84
74
  transactions += (json['elements'] || []).map do |transaction|
85
75
  build_transaction(transaction, account)
86
76
  end
87
- params[:offset] += 25
77
+ params[:offset] += params[:limit]
88
78
  break if (params[:offset] > json['total']) || json['elements'].blank?
89
79
  end
90
80
  transactions
91
81
  end
92
82
 
83
+ def build_transactions_request_params(start_date, end_date)
84
+ # The API allows any limit to be passed, but we better keep
85
+ # being good API citizens and make a loop with a short limit
86
+ {
87
+ fromDate: start_date.strftime('%d/%m/%Y'),
88
+ toDate: end_date.strftime('%d/%m/%Y'),
89
+ limit: 25,
90
+ offset: 0
91
+ }
92
+ end
93
+
93
94
  private
94
95
 
95
96
  def login
96
- selected_positions = get_pin_pad_positions
97
- ticket = pass_pinpad(selected_positions)
97
+ ticket = pass_pinpad(request_pinpad_positions)
98
98
  post_auth(ticket)
99
99
  end
100
100
 
101
- def get_pin_pad_positions
101
+ def request_pinpad_positions
102
102
  add_headers(
103
103
  'Accept' => 'application/json, text/javascript, */*; q=0.01',
104
104
  'Content-Type' => 'application/json; charset=utf-8'
105
105
  )
106
106
 
107
- params = {
107
+ params = request_pinpad_positions_params
108
+ response = JSON.parse(post(LOGIN_ENDPOINT, fields: params.to_json))
109
+ pinpad_numbers = recognize_pinpad_numbers(response['pinpad'])
110
+
111
+ correct_positions(pinpad_numbers, response['pinPositions'])
112
+ end
113
+
114
+ def request_pinpad_positions_params
115
+ {
108
116
  loginDocument: {
109
117
  documentType: 0,
110
118
  document: @dni
@@ -113,12 +121,6 @@ module Bankscrap
113
121
  companyDocument: nil,
114
122
  device: 'desktop'
115
123
  }
116
-
117
- response = JSON.parse(post(LOGIN_ENDPOINT, fields: params.to_json))
118
- current_pinpad_paths = save_pinpad_numbers(response['pinpad'])
119
- pinpad_numbers = recognize_pinpad_numbers(current_pinpad_paths)
120
-
121
- get_correct_positions(pinpad_numbers, response['pinPositions'])
122
124
  end
123
125
 
124
126
  def pass_pinpad(positions)
@@ -137,64 +139,61 @@ module Bankscrap
137
139
  post(POST_AUTH_ENDPOINT, fields: params)
138
140
  end
139
141
 
140
- def save_pinpad_numbers(pinpad)
141
- current_pinpad_paths = []
142
- pinpad.each_with_index do |digit, index|
143
- tmp = Tempfile.new(["pinpad_number_#{index}", '.png'])
144
- File.open(tmp.path, 'wb') { |f| f.write(Base64.decode64(digit)) }
145
- current_pinpad_paths << tmp.path
142
+ def extract_images_from_pinpad(pinpad)
143
+ pinpad.map do |string|
144
+ extract_info_from_encoded_png(string)
146
145
  end
147
-
148
- current_pinpad_paths
149
146
  end
150
147
 
151
- def recognize_pinpad_numbers(current_pinpad_paths)
152
- real_numbers = []
153
- current_numbers = Magick::ImageList.new(*current_pinpad_paths)
148
+ def extract_info_from_encoded_png(encoded_png)
149
+ decoded = Base64.decode64(encoded_png)
150
+ # PNG format first bytes are headers that we can discard. We know where the data chunk starts,
151
+ # so we can directly read the image data. See: https://www.w3.org/TR/PNG-Structure.html
152
+ length = decoded.slice(33, 4).unpack('L>').first
153
+ data = decoded.slice(41, length)
154
+ Zlib::Inflate.inflate(data) # We decompress the data
155
+ .delete("\u0000") # Levenshtein distance doesn't work with null bytes
156
+ .slice(2_000, 5_000) # The whole image is too slow to compare, we can use a chunk in the middle.
157
+ end
158
+
159
+ # For each image received, we compare it with the images of the numbers we already know, in order to find
160
+ # the most similar one (using Levenshtein's string comparison).
161
+ #
162
+ # Note: We can't compare directly the strings we received, even after base64 decoding them, because PNG format
163
+ # compress with Zlib the data of the image.
164
+ def recognize_pinpad_numbers(received_pinpad)
165
+ received_pinpad_images = extract_images_from_pinpad(received_pinpad)
166
+ sorted_pinpad_images = extract_images_from_pinpad(Config::SORTED_PINPAD)
167
+ received_pinpad_numbers = []
168
+ candidates = *0..9
154
169
  0.upto(9) do |i|
155
- pixel_diffs = []
156
- 0.upto(9) do |j|
157
- sample_number_img = Magick::ImageList.new(sample_number_path(j)).first
158
- pixel_diffs << images_diff(sample_number_img, current_numbers[i])
170
+ number = find_more_similar_image(sorted_pinpad_images, received_pinpad_images[i], candidates)
171
+ candidates.delete(number) # We can reduce our search space
172
+ received_pinpad_numbers << number
173
+ end
174
+ received_pinpad_numbers
175
+ end
176
+
177
+ def find_more_similar_image(sorted_pinpad_images, image, candidates)
178
+ more_similar_number = -1
179
+ min = 99_999 # An arbitrary, high enough upper limit
180
+ candidates.each do |j|
181
+ l = Levenshtein.distance(image, sorted_pinpad_images[j])
182
+ # If the distance is lower, we have found a better candidate
183
+ if l < min
184
+ min = l
185
+ more_similar_number = j
159
186
  end
160
- real_numbers << pixel_diffs.each_with_index.min.last
161
187
  end
162
- real_numbers
163
- end
164
-
165
- def sample_number_path(number)
166
- File.join(File.dirname(__FILE__), "#{SAMPLE_ROOT_PATH}/#{number}.png")
188
+ more_similar_number
167
189
  end
168
190
 
169
- def images_diff(sample_number_img, current_number_img)
170
- diff = 0
171
- sample_pixels = pixels_from_coordinates(sample_number_img, 0, 0)
172
- current_pixels = pixels_from_coordinates(current_number_img, 0, 0)
173
- current_pixels.each_with_index do |pixel, index|
174
- sample_pixel = sample_pixels[index]
175
- red_diff = (pixel.red - sample_pixel.red).abs
176
- green_diff = (pixel.green - sample_pixel.green).abs
177
- blue_diff = (pixel.blue - sample_pixel.blue).abs
178
-
179
- diff += red_diff + green_diff + blue_diff
191
+ def correct_positions(pinpad_numbers, positions)
192
+ positions.map do |position|
193
+ # Positions array is 1-based
194
+ number_to_find = @password[position - 1].to_i
195
+ pinpad_numbers.index(number_to_find)
180
196
  end
181
- diff
182
- end
183
-
184
- def pixels_from_coordinates(img, x, y)
185
- img.get_pixels(x, y, SAMPLE_WIDTH, SAMPLE_HEIGHT)
186
- end
187
-
188
- def get_correct_positions(pinpad_numbers, positions)
189
- first_digit = @password[positions[0] - 1]
190
- second_digit = @password[positions[1] - 1]
191
- third_digit = @password[positions[2] - 1]
192
-
193
- [
194
- pinpad_numbers.index(first_digit.to_i),
195
- pinpad_numbers.index(second_digit.to_i),
196
- pinpad_numbers.index(third_digit.to_i)
197
- ]
198
197
  end
199
198
 
200
199
  # Build an Account object from API data
@@ -0,0 +1,65 @@
1
+ class Config
2
+ SORTED_PINPAD = [
3
+ # zero
4
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAA9klEQVR42u3ZsQ2DMBCFYSb0AB6AngEYgAEYgN4DeAAPwBYMQI+jZ8kUVoqkIeH4' \
5
+ 'T7oCd5/vLJ9Flx8WXbtwHEdJwFbBj2tpwIDvfc4B09KAHwa++2ACmJYGDBgwoyVgWhow4LuCQwh5HMeSy7LkbdvsgodhyN77AhW87/vyfSX6MnCM' \
6
+ 'MTvn8rqu59q+7wU8TZM9sFCqcBuqtjbCHLie23dnGjBgwIAB/xqs60d3ru7ediM0gJgDa5pSJed5PtG1uhpKTI6WKaVSZSFrCm3+taTxUtm2N89D' \
7
+ 'wIABAwYMGDBgwIABAwYM+Lv49Cc9YFoaMGDAgP8oXr4bsMoCtb2MAAAAAElFTkSuQmCC',
8
+
9
+ # one
10
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAqUlEQVR42u3YwQnEIBAF0FRoAekiBdiRBaSMFODdAnLXRSGHhb3uwuob+ChzeyAy' \
11
+ 'urXFagMGBgYGBgYGBgYGBgYGBgYGnhpcax0BdqSBP1YppaWURs7znB+cc24xxrbv+1iXOdIdCwwMDAwMDAz81brvu13X1Y7jGOn73psW3IEhhLf0' \
12
+ 'ntcSMDAwMDAw8NrgWf6ogYFXBbulgYGBgYGBgYF/BX5GzX8bN1/rU9jSZVPlGwAAAABJRU5ErkJggg==',
13
+
14
+ # two
15
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAABDUlEQVR42u3awQmEMBCFYSu0AAvwbgEWYAEW4N0CLCMFeLeA3B15gYAueFmWuIz/' \
16
+ 'QBCPX/ImMWBlL6sKMGDAgAEDBgz4EfC+72kAJtKAAQMGDBjwr0tHLmAi/Qaw50/MouAYo83zbH3fpzFNk23b5jfSXddZ0zQJKnjbtum9JLoYeFkW' \
17
+ 'q+va1nW9rHieAHfgYRjSCn9Wjrc78B1MsdZkuAMryuc4q9THirni7v4cFl79WzLOj4G1KwurntbG5RosoKDq3dLYR8D5LM79HEJIvewSPI7jBXve' \
18
+ 'uNyBM0xPrWoemgSXYO3Ggt0NroeAXw7+9goLmEgDBgwYMGDAgAEDBgwYsPGPB2AiDRjwf9cBpUezPc4J7GcAAAAASUVORK5CYII=',
19
+
20
+ # three
21
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAABI0lEQVR42u3YzW2DQBBAYVdIARRAFxRAARTAnQIogALoggK4s9FDWilCziVW1s7s' \
22
+ 'G2klXzh8zN+aR6osHr956DzP6wiOCq6upAULFixYsOB/Cv60S4pgS/pN8VeVIdiSFixYsGDBFYGXZUnDMKS+79M0TWnf97hggE3TpHEc0zzPqeu6' \
23
+ '1LZtUXQxMCiwQHMcx3GBeRHhwEABg/welDYnHJjefQajrOnp8FOaTNPLZH3btthggEDvPR0WTHbXdb1KGTS/q7l40Nf0cTgwq+fZ+snTOxyY8mXn' \
24
+ '3tcSgytkhunTfMvK6JzdkoOraA+zi8lyntCckrest64lzr28/Xv4Qvz01VOwHwBeeJuCo4CrK2nBggULFixYsGDBggULFixY8GfHFxy1uLw1bfbk' \
25
+ 'AAAAAElFTkSuQmCC',
26
+
27
+ # four
28
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAA60lEQVR42u3ZwQ2EIBCFYSukAAuwCwugAArgbgEWQAEWwJ0CvIMZEjYbz7sahn+S' \
29
+ 'SQy3L/MgqFMZrCbAgAEDBgxYKTjnXBswkQYMGDBgwIABA+7ktgSYSD8A7iUZr4HP8yzrupZ938eItLW2GGPKtm36wSGEip3nWT9YoizQYSbsva9g' \
30
+ 'gasHH8dRkRJpKfXgZVnqydxKNVhgEuWU0hjgdirLhFvL2n3qqiZ8bwEL9skpv3qXHubiEWP8nNjOufqsGtz273fzeggYMODuwf/4igKYSAMGDBhw' \
31
+ 'D2Ct/5gAs4cBAwYMGDBgwIB/VBdvBrVceKwsigAAAABJRU5ErkJggg==',
32
+
33
+ # five
34
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAA5klEQVR42u3XwQmEMBCFYStMASnAewqwAAtIFynAAiwgBXi3AO+JTMDFBfeyC+LO' \
35
+ '/IEBrx9vnEm6+uUppbT6t9MBVnqOgMwkbA5srqUBAwYMGDBgwL/flADT0oABP+LfAkxLAwb8OHBK6bLUgp1zte/7OgzDW6kG350o4LvBMcaac67L' \
36
+ 'stgAn8t7X6dp0gte1/X1LQmP49jg8zzb2cMhhFZmwDLEJGV14E8TWi1Y2vbqkqG2pWUan1Petq2tKNVD62hfM2vpSFYuHlI8DwEDBgwYMGDAgAED' \
37
+ 'BgwYMGDAgAEDBgzYHHgHAj26dUWtKS8AAAAASUVORK5CYII=',
38
+
39
+ # six
40
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAABEElEQVR42u3awQmDQBCFYSu0AAvwbgEWYAEW4N0CLMMuLMC7G97CBBRyzMY8/4GB' \
41
+ 'kEv4nNm3CKnSw6oCDBgwYMCAAf8efBxHbsCsNGDAdy0dWcCsNGDAgAEDBuwJ3vc9zfOc+r7PPU1T2rbNEyxs13WpbduMVutz0zRF0cXAAtZ1fcLp' \
42
+ 'Iei7cRz9wFphTfhay7LktgSrHxNaAdY0h2F4h5bW2has86qQEtQ+tAK8rusptAS2DS1N9Fqath7EY0Irris7cEzyGlKfrqu/ByuY4rwGOqZreQ+r' \
43
+ 'FFg6x0JGC23/tiS4uvQdzOshYMCAAQMGDBgwYMBm4G/+hQpwqR++5Uo/DkxoATYHO5xpwKy0Wb0ASlusiY0vxqcAAAAASUVORK5CYII=',
44
+
45
+ # seven
46
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAA70lEQVR42u3ZwQmEMBCFYSu0AAvIPQVYhl2kgBRgASnAuwV4N/ICC7IgLAu70cw/' \
47
+ 'MAjePmcyQ7DLxqIDDBgwYMCAAQMGDBjw78D7vpc0DX7qR/i6pc2BGVqA68bVkQNMSwMG/FHEGHMI4TKbA4/jmIdhKM9z6l3f922ClefYtq2Ap2my' \
48
+ 'AVabq7rLsrQHFuod5pzL3nsbUzqlVKqrKpsAvwaWiT28rmup7j/XUVWwprLAgjcPrrGKqoLVxqquhpYJsFaR0sTlYZ7nKquI2xJgwIABAwYMGDDg' \
49
+ 'J4Hv+v8YMC0NGDDgOw9AwLQ0YMCA7xwHcYfImqg1fiAAAAAASUVORK5CYII=',
50
+
51
+ # eight
52
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAABLUlEQVR42u3asQ2DMBCFYSZkAAagZwAGYAAGoGcABmAABqBnAHocvZMsIRSqRE58' \
53
+ '/JauSIpIH3d+2FKK8LBVfPPHjuOwAuwV/LiRBgwYcPIgzA786QPIbqQfBya0AAMGDBgwYMCAAQN+CHgcx9C2rdUwDGHfd79gIcuyDH3fG7aqKquU' \
54
+ '6GTgeZ4Nqw7HtW2bfSe8O7Cgwr3rusodeJomA6ur51XXtY24O7D2adM0VkLrc9zH67r6DC1BBVSnY2lvu0zpc4eFXJYldF3nt8NxfK+vIAWWHoI7' \
55
+ '8F0a36V39mCNrxL5upTQ6rw7sPZsPGXFsY7dPR9GXKW03sXXlE55yvrZbUndVqW+OHA9BAwYMGDAOYJz+IcdYEYaMGDAbsCeUhgwIw0YMGDAgP93' \
56
+ 'vQCjaKjz88HBPgAAAABJRU5ErkJggg==',
57
+
58
+ # nine
59
+ 'iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAABGUlEQVR42u3YsQ2EMAyFYSZkAAagZwAGYIAMQM8AjMEA9AxAj08vUiSEctWdcpz5' \
60
+ 'LaUg3YftxFDZw6ICDBgwYMAfxnEccQGmpAEDBgwY8L2vGcCUNGDAgAEDBpyNfd9tHEfr+z6uaZr8grdts6ZprG3bCBVcz4K7BIcQIlBZTrEsi9V1' \
61
+ 'bfM8+wMLq6xeo+s6G4bBH1iZzPVs6md3YPXuFabyLt3HxcDq03OWhVVfa88lWCGsgGkp67nMuxo8lFmdzuu6+u7hd+EWrBJWz+auq9y+m8FD5Xw9' \
62
+ 'tNKeK7CAGjDOh5ZeQMkp6yc9rJlaGS2ZVT4PAT8JfKef5oApacCA/xr8jfMFMCUNGDBgwIABAwZcAuzx2xiw93gBoFurmappddIAAAAASUVORK5C' \
63
+ 'YII='
64
+ ].freeze
65
+ end
@@ -1,5 +1,5 @@
1
1
  module Bankscrap
2
2
  module ING
3
- VERSION = '2.0.1'.freeze
3
+ VERSION = '2.0.2'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bankscrap-ing
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raúl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-29 00:00:00.000000000 Z
11
+ date: 2017-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bankscrap
@@ -25,25 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rmagick
28
+ name: levenshtein-ffi
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.2'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 2.2.2
33
+ version: '1.1'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - "~>"
42
39
  - !ruby/object:Gem::Version
43
- version: '2.2'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 2.2.2
40
+ version: '1.1'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: bundler
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,40 +66,6 @@ dependencies:
72
66
  - - "~>"
73
67
  - !ruby/object:Gem::Version
74
68
  version: '10.0'
75
- - !ruby/object:Gem::Dependency
76
- name: byebug
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '8.2'
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: 8.2.5
85
- type: :development
86
- prerelease: false
87
- version_requirements: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: '8.2'
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: 8.2.5
95
- - !ruby/object:Gem::Dependency
96
- name: rubocop
97
- requirement: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - "~>"
100
- - !ruby/object:Gem::Version
101
- version: 0.39.0
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - "~>"
107
- - !ruby/object:Gem::Version
108
- version: 0.39.0
109
69
  description:
110
70
  email:
111
71
  - raulmarcosl@gmail.coms
@@ -122,16 +82,7 @@ files:
122
82
  - bankscrap-ing.gemspec
123
83
  - lib/bankscrap-ing.rb
124
84
  - lib/bankscrap/ing/bank.rb
125
- - lib/bankscrap/ing/numbers/0.png
126
- - lib/bankscrap/ing/numbers/1.png
127
- - lib/bankscrap/ing/numbers/2.png
128
- - lib/bankscrap/ing/numbers/3.png
129
- - lib/bankscrap/ing/numbers/4.png
130
- - lib/bankscrap/ing/numbers/5.png
131
- - lib/bankscrap/ing/numbers/6.png
132
- - lib/bankscrap/ing/numbers/7.png
133
- - lib/bankscrap/ing/numbers/8.png
134
- - lib/bankscrap/ing/numbers/9.png
85
+ - lib/bankscrap/ing/config.rb
135
86
  - lib/bankscrap/ing/version.rb
136
87
  homepage: ''
137
88
  licenses:
@@ -153,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
104
  version: '0'
154
105
  requirements: []
155
106
  rubyforge_project:
156
- rubygems_version: 2.5.1
107
+ rubygems_version: 2.6.8
157
108
  signing_key:
158
109
  specification_version: 4
159
110
  summary: ING adapter for Bankscrap
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file