ng-bank-parser 0.1.3 → 0.1.4

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