bankscrap-ing 2.0.1 → 2.0.2

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 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