ng-bank-parser 0.1.3 → 0.1.4

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: 0e5a7db57078dcd107ad0639d82e75878f2a20ca
4
- data.tar.gz: 643bd67066a3d7403c441560c5fb7da8791c403c
3
+ metadata.gz: 19849fae342789d9fc403b205e4c2b476dff411a
4
+ data.tar.gz: 06509361c35618a53005cd7952521731dccf1119
5
5
  SHA512:
6
- metadata.gz: 6237746ad1515a706fccefd269d85afe998e3fdb5ef34a7500b3999bfc03f2feba27183dfd7ede81aca31d5b46e0a23095a4d1d578c173b0c109fdbd7205e361
7
- data.tar.gz: d1510c04d081e6a94a7c2169bc2bf7177d1cad0c5ab4bd800058ac60405e7a1f6e2f68179367e3e1adb12ce53199690bd9ef46b2c01ea71b4382195db3942532
6
+ metadata.gz: f6cf9a75e0f1ce3b40406852cb0a36678b32e8e03e20f4ce23dcf1283ee6be8b30bdd1aba797c13c544b7180447657733ca321cde9fff7539738ec859fe417ac
7
+ data.tar.gz: 30fece1d8504473ea6074ac278bd189def9b2936ab1646e753f24a2be25e3dfa0c3ceb9ac354e365666b5a06ac64012e6c6618be26acdc5158850f2f004bd136
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ng-bank-parser (0.1.2)
4
+ ng-bank-parser (0.1.4)
5
5
  activesupport
6
- httmultiparty
7
6
  nokogiri
8
7
  pdf-reader
8
+ rest-client
9
9
  roo
10
10
 
11
11
  GEM
@@ -20,21 +20,17 @@ GEM
20
20
  tzinfo (~> 1.1)
21
21
  afm (0.2.2)
22
22
  diff-lcs (1.2.5)
23
+ domain_name (0.5.24)
24
+ unf (>= 0.0.5, < 1.0.0)
23
25
  hashery (2.1.1)
24
- httmultiparty (0.3.16)
25
- httparty (>= 0.7.3)
26
- mimemagic
27
- multipart-post
28
- httparty (0.13.5)
29
- json (~> 1.8)
30
- multi_xml (>= 0.5.2)
26
+ http-cookie (1.0.2)
27
+ domain_name (~> 0.5)
31
28
  i18n (0.7.0)
32
29
  json (1.8.3)
33
- mimemagic (0.3.0)
30
+ mime-types (2.6.1)
34
31
  mini_portile (0.6.2)
35
32
  minitest (5.8.0)
36
- multi_xml (0.5.5)
37
- multipart-post (2.0.0)
33
+ netrc (0.10.3)
38
34
  nokogiri (1.6.6.2)
39
35
  mini_portile (~> 0.6.0)
40
36
  pdf-reader (1.3.3)
@@ -44,6 +40,10 @@ GEM
44
40
  ruby-rc4
45
41
  ttfunk
46
42
  rake (10.4.2)
43
+ rest-client (1.8.0)
44
+ http-cookie (>= 1.0.2, < 2.0)
45
+ mime-types (>= 1.16, < 3.0)
46
+ netrc (~> 0.7)
47
47
  roo (2.1.1)
48
48
  nokogiri (~> 1)
49
49
  rubyzip (~> 1.1, < 2.0.0)
@@ -66,6 +66,9 @@ GEM
66
66
  ttfunk (1.4.0)
67
67
  tzinfo (1.2.2)
68
68
  thread_safe (~> 0.1)
69
+ unf (0.1.4)
70
+ unf_ext
71
+ unf_ext (0.0.7.1)
69
72
 
70
73
  PLATFORMS
71
74
  ruby
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Ng::Bank::Parser
2
2
  This is a simple gem to parse Nigerian bank statements of all formats. If your bank and/or file format is not supported, consider reading the contribute wiki and submitting a pull request.
3
3
 
4
+ ## API
5
+ Because not everyone develops in rails, we created a public API to use the gem at http://bank-parser.devcenter.co/parse. The parameters are (bank_key, file_path, password). Read the *Usage* section for more information
6
+
7
+ http://bank-parser.devcenter.co/parse(bank_key, file_path, password)
8
+
4
9
  ## Installation
5
10
 
6
11
  Add this line to your application's Gemfile:
@@ -25,7 +25,7 @@ module NgBankParser
25
25
  format: "pdf",
26
26
  valid: "lib/ng-bank-parser/fixtures/firstbank-pdf-valid.pdf",
27
27
  fixture_password: 19856,
28
- invalid: "lib/ng-bank-parser/fixtures/firstbank-pdf-invalid.xlsx",
28
+ invalid: "lib/ng-bank-parser/fixtures/firstbank-pdf-invalid.pdf",
29
29
  extensions: ["pdf"]
30
30
  }]
31
31
  }]
@@ -0,0 +1,160 @@
1
+ %PDF-1.3
2
+ 3 0 obj
3
+ <</Type /Page
4
+ /Parent 1 0 R
5
+ /Resources 2 0 R
6
+ /Contents 4 0 R>>
7
+ endobj
8
+ 4 0 obj
9
+ <</Length 165>>
10
+ stream
11
+ 0.57 w
12
+ 0 G
13
+ BT
14
+ /F1 16 Tf
15
+ 16 TL
16
+ 0 g
17
+ 56.69 785.20 Td
18
+ (Hello world!) Tj
19
+ ET
20
+ BT
21
+ /F1 16 Tf
22
+ 16 TL
23
+ 0 g
24
+ 56.69 756.85 Td
25
+ (This a random PDF file for testing our parsers.) Tj
26
+ ET
27
+ endstream
28
+ endobj
29
+ 1 0 obj
30
+ <</Type /Pages
31
+ /Kids [3 0 R ]
32
+ /Count 1
33
+ /MediaBox [0 0 595.28 841.89]
34
+ >>
35
+ endobj
36
+ 5 0 obj
37
+ <</BaseFont/Helvetica/Type/Font
38
+ /Encoding/WinAnsiEncoding
39
+ /Subtype/Type1>>
40
+ endobj
41
+ 6 0 obj
42
+ <</BaseFont/Helvetica-Bold/Type/Font
43
+ /Encoding/WinAnsiEncoding
44
+ /Subtype/Type1>>
45
+ endobj
46
+ 7 0 obj
47
+ <</BaseFont/Helvetica-Oblique/Type/Font
48
+ /Encoding/WinAnsiEncoding
49
+ /Subtype/Type1>>
50
+ endobj
51
+ 8 0 obj
52
+ <</BaseFont/Helvetica-BoldOblique/Type/Font
53
+ /Encoding/WinAnsiEncoding
54
+ /Subtype/Type1>>
55
+ endobj
56
+ 9 0 obj
57
+ <</BaseFont/Courier/Type/Font
58
+ /Encoding/WinAnsiEncoding
59
+ /Subtype/Type1>>
60
+ endobj
61
+ 10 0 obj
62
+ <</BaseFont/Courier-Bold/Type/Font
63
+ /Encoding/WinAnsiEncoding
64
+ /Subtype/Type1>>
65
+ endobj
66
+ 11 0 obj
67
+ <</BaseFont/Courier-Oblique/Type/Font
68
+ /Encoding/WinAnsiEncoding
69
+ /Subtype/Type1>>
70
+ endobj
71
+ 12 0 obj
72
+ <</BaseFont/Courier-BoldOblique/Type/Font
73
+ /Encoding/WinAnsiEncoding
74
+ /Subtype/Type1>>
75
+ endobj
76
+ 13 0 obj
77
+ <</BaseFont/Times-Roman/Type/Font
78
+ /Encoding/WinAnsiEncoding
79
+ /Subtype/Type1>>
80
+ endobj
81
+ 14 0 obj
82
+ <</BaseFont/Times-Bold/Type/Font
83
+ /Encoding/WinAnsiEncoding
84
+ /Subtype/Type1>>
85
+ endobj
86
+ 15 0 obj
87
+ <</BaseFont/Times-Italic/Type/Font
88
+ /Encoding/WinAnsiEncoding
89
+ /Subtype/Type1>>
90
+ endobj
91
+ 16 0 obj
92
+ <</BaseFont/Times-BoldItalic/Type/Font
93
+ /Encoding/WinAnsiEncoding
94
+ /Subtype/Type1>>
95
+ endobj
96
+ 2 0 obj
97
+ <<
98
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
99
+ /Font <<
100
+ /F1 5 0 R
101
+ /F2 6 0 R
102
+ /F3 7 0 R
103
+ /F4 8 0 R
104
+ /F5 9 0 R
105
+ /F6 10 0 R
106
+ /F7 11 0 R
107
+ /F8 12 0 R
108
+ /F9 13 0 R
109
+ /F10 14 0 R
110
+ /F11 15 0 R
111
+ /F12 16 0 R
112
+ >>
113
+ /XObject <<
114
+ >>
115
+ >>
116
+ endobj
117
+ 17 0 obj
118
+ <<
119
+ /Producer (jsPDF 20120619)
120
+ /CreationDate (D:20150829130726)
121
+ >>
122
+ endobj
123
+ 18 0 obj
124
+ <<
125
+ /Type /Catalog
126
+ /Pages 1 0 R
127
+ /OpenAction [3 0 R /FitH null]
128
+ /PageLayout /OneColumn
129
+ >>
130
+ endobj
131
+ xref
132
+ 0 19
133
+ 0000000000 65535 f
134
+ 0000000301 00000 n
135
+ 0000001530 00000 n
136
+ 0000000009 00000 n
137
+ 0000000087 00000 n
138
+ 0000000388 00000 n
139
+ 0000000478 00000 n
140
+ 0000000573 00000 n
141
+ 0000000671 00000 n
142
+ 0000000773 00000 n
143
+ 0000000861 00000 n
144
+ 0000000955 00000 n
145
+ 0000001052 00000 n
146
+ 0000001153 00000 n
147
+ 0000001246 00000 n
148
+ 0000001338 00000 n
149
+ 0000001432 00000 n
150
+ 0000001754 00000 n
151
+ 0000001836 00000 n
152
+ trailer
153
+ <<
154
+ /Size 19
155
+ /Root 18 0 R
156
+ /Info 17 0 R
157
+ >>
158
+ startxref
159
+ 1940
160
+ %%EOF
@@ -1,7 +1,6 @@
1
1
  require 'pdf-reader'
2
2
  require_relative 'firstbank-pdf-parser/helpers'
3
3
 
4
-
5
4
  module NgBankParser
6
5
  class FirstbankPdf
7
6
  extend FirstbankPdfHelpers
@@ -14,7 +13,9 @@ module NgBankParser
14
13
  return error_message 'Invalid file format'
15
14
  end
16
15
 
17
- if has_encryption? path
16
+ file = open(path)
17
+
18
+ if has_encryption? file
18
19
  if password
19
20
  unless get_unlocked_pdf? path, password
20
21
  return error_message 'Password supplied for decryption is invalid.'
@@ -41,10 +42,8 @@ module NgBankParser
41
42
  else
42
43
  return error_message 'Could not find any transactions'
43
44
  end
44
-
45
45
  end
46
46
 
47
-
48
47
  private
49
48
 
50
49
  def self.extract_transactions(jagged_array = [[]])
@@ -1,6 +1,7 @@
1
1
  require 'pdf-reader'
2
2
  require 'date'
3
3
  require 'open-uri'
4
+ require 'securerandom'
4
5
  require_relative 'statement_utils'
5
6
  require_relative '../../pdf-unlocker.rb'
6
7
 
@@ -10,27 +11,37 @@ module NgBankParser
10
11
 
11
12
  @@pdf_reader = nil
12
13
  @@raw_transactions = [[]]
13
-
14
- def has_encryption? path
14
+ @@account_name = nil
15
+ @@account_number = nil
16
+ @@last_balance = nil
17
+ @@statement_period = nil
18
+ @@from_date = nil
19
+ @@to_date = nil
20
+
21
+ def has_encryption? file
15
22
  begin
16
- @@pdf_reader = PDF::Reader.new(path)
23
+ @@pdf_reader = PDF::Reader.new(file)
17
24
  false
18
25
  rescue PDF::Reader::EncryptedPDFError
19
26
  true
20
27
  end
21
28
  end
22
29
 
23
-
24
30
  def get_unlocked_pdf? path, password
25
- response = PDFUnlocker.new(File.new(path), password).unlocked_pdf
31
+ response = PDFUnlocker.unlock(path, password)
32
+
26
33
  return false unless response
27
34
  if response.include? 'Unlock Failed'
28
35
  return false
29
36
  else
30
37
  pseudo_file = StringIO.new
31
38
  pseudo_file.write(response)
32
- @@pdf_reader = PDF::Reader.new(pseudo_file)
33
- return true
39
+ begin
40
+ @@pdf_reader = PDF::Reader.new(pseudo_file)
41
+ return true
42
+ rescue
43
+ return false
44
+ end
34
45
  end
35
46
  end
36
47
 
@@ -14,8 +14,13 @@ module NgBankParser
14
14
  end
15
15
 
16
16
  file = open(url)
17
- @reader = PDF::Reader.new(file)
17
+
18
+ if has_encryption? file
19
+ return invalid_file
20
+ end
21
+
18
22
  set_up_first_page
23
+
19
24
  if is_valid_pdf?
20
25
  set_account_details
21
26
  set_transactions
@@ -27,6 +32,15 @@ module NgBankParser
27
32
 
28
33
  private
29
34
 
35
+ def has_encryption? path
36
+ begin
37
+ @reader = PDF::Reader.new(path)
38
+ false
39
+ rescue PDF::Reader::EncryptedPDFError
40
+ true
41
+ end
42
+ end
43
+
30
44
  def set_up_first_page
31
45
  @first_page_text = @reader.pages.first.text.remove_empty_lines
32
46
  set_column_positions(@first_page_text.lines[TABLE_HEADER_LINE_INDEX])
@@ -12,8 +12,8 @@ module NgBankParser
12
12
  private
13
13
 
14
14
  def set_transactions
15
- @transactions ||= Array.new
16
- @transaction_strings ||= Array.new
15
+ @transactions = Array.new
16
+ @transaction_strings = Array.new
17
17
  @reader.pages[0..-2].each do |page|
18
18
  seperate_lines_into_transaction_strings(page.text.remove_empty_lines.lines)
19
19
  end
@@ -1,21 +1,35 @@
1
- require 'httmultiparty'
1
+ require 'rest-client'
2
2
 
3
3
  module NgBankParser
4
4
  class PDFUnlocker
5
- include HTTMultiParty
6
- base_uri 'http://pdf-unlocker.herokuapp.com'
7
5
 
8
- def initialize(file, password)
9
- @pdf = file
6
+ def self.unlock(path, password)
7
+ @path = path
10
8
  @password = password
9
+
10
+ if File.exists? @path
11
+ unlock_pdf_file
12
+ else
13
+ unlock_pdf_url
14
+ end
11
15
  end
12
16
 
13
-
14
- def unlocked_pdf
15
- options = { :pdf => @pdf, :password => @password }
17
+ def self.unlock_pdf_file
18
+ url = 'http://pdf-unlocker.herokuapp.com/rest/pdf/unlock'
19
+
20
+ begin
21
+ response = RestClient.post url, {:password => @password, :pdf => File.new(@path, 'rb')}
22
+ rescue
23
+ response = nil
24
+ end
25
+ end
26
+
27
+ def self.unlock_pdf_url
28
+ url = 'http://pdf-unlocker.herokuapp.com/rest/pdf/unlock_with_file_url'
29
+
16
30
  begin
17
- response = self.class.post('/rest/pdf/unlock', :query => options, :detect_mime_type => true).parsed_response
18
- rescue StandardError
31
+ response = RestClient.post url, {:password => @password, :file_url => @path, :multipart => true}
32
+ rescue
19
33
  response = nil
20
34
  end
21
35
  end
@@ -1,43 +1,61 @@
1
+ require 'net/http'
2
+
1
3
  module NgBankParser
2
4
  class Router
3
- @banks_hash = $Banks
4
- @supported_extension_array = []
5
- @selected_bank_index
5
+ @banks = $Banks
6
6
 
7
7
  #this takes our bank parser along with the bank name supplied from the payload so as to compare
8
8
  #and see if the file extension is available for that bank
9
9
  #it's result is to fill up the @supported_extension_array with the supported bank extensions
10
10
  def self.parse(bank_key, path, password = nil)
11
- @password = password;
12
- @selected_bank_index = @banks_hash.index {|x| x[:key] == bank_key}
11
+ @path = path
12
+ @password = password
13
+ @selected_bank = @banks.find {|x| x[:key] == bank_key}
13
14
 
14
- if @selected_bank_index.nil?
15
+ if @selected_bank.nil?
15
16
  return {status: 0, message: "Your bank is not yet supported"}
16
- else
17
- @supported_extension_array += @banks_hash[@selected_bank_index][:parsers].map {|e| e[:extensions]}
18
- parser_picker(path)
19
- end
17
+ end
18
+
19
+ unless file_exists(path)
20
+ return {status: 0, message: "File does not exist or is not accesible"}
21
+ end
22
+
23
+ extensions = @selected_bank[:parsers].map {|e| e[:extensions]}
24
+ @supported_extensions = extensions.reduce(:concat)
25
+ pick_parser()
20
26
  end
21
27
 
22
28
  private
23
29
 
24
30
  #this uses the extension in the file of the uploaded payload to check support in @supported_extension_array
25
31
  #and goes on to pick the parser to use for the operation
26
- def self.parser_picker(path)
27
- extension_name = File.extname(path).delete('.')
28
- if @supported_extension_array.reduce(:concat).include?(extension_name)
29
- ng_bank_parsers(path)
32
+ def self.pick_parser()
33
+ bank_name = @selected_bank[:name]
34
+ extension_name = File.extname(@path).delete('.')
35
+
36
+ if @supported_extensions.include? extension_name
37
+ parser = @selected_bank[:parsers].find {|p| p[:extensions].include? extension_name}
38
+ parse_with(parser)
30
39
  else
31
- return {status: 0, message:"The '.#{extension_name}' file format is not supported for your bank."}
40
+ return {status: 0, message:"The '.#{extension_name}' file format is not supported for this bank (#{bank_name})."}
32
41
  end
33
42
  end
34
43
 
35
44
  #Builds the the parser to use from the name and file format of the uploaded file
36
- def self.ng_bank_parsers(path)
37
- key = @banks_hash[@selected_bank_index][:key].capitalize
38
- format = @banks_hash[@selected_bank_index][:parsers].map { |e| e[:format].capitalize }
39
- class_name = key + format.reduce(:concat)
40
- NgBankParser.const_get(class_name).parse(path, @password)
45
+ def self.parse_with(parser)
46
+ class_name = @selected_bank[:key].capitalize + parser[:format].capitalize
47
+ class_object = NgBankParser.const_get(class_name)
48
+ parser_response = class_object.parse(@path, @password)
49
+ end
50
+
51
+ def self.file_exists(path)
52
+ return true if File.exists?(path)
53
+
54
+ uri = URI(path)
55
+
56
+ request = Net::HTTP.new uri.host
57
+ response= request.request_head uri.path
58
+ return response.code.to_i == 200
41
59
  end
42
60
 
43
61
  end
@@ -1,3 +1,3 @@
1
1
  module NgBankParser
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "roo"
28
28
  spec.add_dependency "pdf-reader"
29
29
  spec.add_dependency "activesupport"
30
- spec.add_dependency 'httmultiparty'
30
+ spec.add_dependency 'rest-client'
31
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ng-bank-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Opemipo Aikomo
@@ -112,7 +112,7 @@ dependencies:
112
112
  - !ruby/object:Gem::Version
113
113
  version: '0'
114
114
  - !ruby/object:Gem::Dependency
115
- name: httmultiparty
115
+ name: rest-client
116
116
  requirement: !ruby/object:Gem::Requirement
117
117
  requirements:
118
118
  - - '>='
@@ -148,7 +148,7 @@ files:
148
148
  - bin/setup
149
149
  - lib/ng-bank-parser.rb
150
150
  - lib/ng-bank-parser/banks.rb
151
- - lib/ng-bank-parser/fixtures/firstbank-pdf-invalid.xlsx
151
+ - lib/ng-bank-parser/fixtures/firstbank-pdf-invalid.pdf
152
152
  - lib/ng-bank-parser/fixtures/firstbank-pdf-valid.pdf
153
153
  - lib/ng-bank-parser/fixtures/gtb-excel-invalid.pdf
154
154
  - lib/ng-bank-parser/fixtures/gtb-excel-valid.xls