aba_numbers 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Adrian Madrid
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # AbaNumbers
2
+
3
+ Get a list of Federal Reserve E-Payments Routing Directory from the Federal Reserve Financial Services.
4
+ This database will provide you with a known list of financial entities and their ABA (routing) numbers plus other useful information like bank name, city, state, etc.
5
+ You can also get a way to validate an unknown ABA number through a simple formula.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'aba_numbers'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install aba_numbers
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aba_numbers/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'aba_numbers'
8
+ gem.version = AbaNumbers::VERSION
9
+ gem.authors = ['Adrian Madrid']
10
+ gem.email = %w(aemadrid@gmail.com)
11
+ gem.description = %q{Get a list of Federal Reserve E-Payments Routing Directory}
12
+ gem.summary = %q{Get a list of Federal Reserve E-Payments Routing Directory from the Federal Reserve Financial Services}
13
+ gem.homepage = 'https://github.com/NorthPointAdvisors/aba_numbers'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = %w( lib )
19
+
20
+ gem.add_development_dependency 'rspec', '~> 2.8.0'
21
+ gem.add_development_dependency 'simplecov', '~> 0.7.1'
22
+ end
File without changes
@@ -0,0 +1,14 @@
1
+ module AbaNumbers
2
+
3
+ ROOT_PATH = File.expand_path(File.dirname(File.dirname(__FILE__)))
4
+ LIB_PATH = File.join ROOT_PATH, 'lib'
5
+ DB_PATH = File.join ROOT_PATH, 'db'
6
+ TMP_PATH = File.join ROOT_PATH, 'tmp'
7
+
8
+ end
9
+
10
+ $LOAD_PATH.unshift(AbaNumbers::LIB_PATH) unless $LOAD_PATH.include?(AbaNumbers::LIB_PATH)
11
+
12
+ require 'aba_numbers/version'
13
+ require 'aba_numbers/validation'
14
+ require 'aba_numbers/database'
@@ -0,0 +1,130 @@
1
+ require 'uri'
2
+ require 'open-uri'
3
+ require 'openssl'
4
+ require 'date'
5
+ require 'net/http'
6
+ require 'net/https'
7
+
8
+ module AbaNumbers
9
+ class Database
10
+
11
+ class Row
12
+
13
+ include Comparable
14
+
15
+ attr_reader :aba_number, :short_name, :name, :state, :city
16
+
17
+ def initialize(line)
18
+ @aba_number = line[0, 9]
19
+ @short_name = line[9, 18].strip
20
+ @name = line[27, 36].strip
21
+ @state = line[63, 2]
22
+ @city = line[65, 25].strip
23
+ @funds_transfer = line[90, 1]
24
+ @settlement_only = line[91, 1]
25
+ @securities = line[92, 1]
26
+ @last_updated = line[93, 8].strip
27
+ end
28
+
29
+ def funds_transfer
30
+ @funds_transfer == 'Y'
31
+ end
32
+
33
+ def settlement_only
34
+ @settlement_only == 'S'
35
+ end
36
+
37
+ def securities
38
+ @securities == 'Y'
39
+ end
40
+
41
+ def last_updated
42
+ return nil if @last_updated.empty?
43
+ Date.new @last_updated[0, 4].to_i, @last_updated[4, 2].to_i, @last_updated[6, 2].to_i
44
+ end
45
+
46
+ def to_s
47
+ "#<AbaNumbers::Database::Row aba_number=#{aba_number.inspect} " +
48
+ "short_name=#{short_name.inspect} name=#{name.inspect} " +
49
+ "state=#{state.inspect} city=#{city.inspect} " +
50
+ "funds_transfer=#{funds_transfer.inspect} settlement_only=#{settlement_only.inspect} " +
51
+ "securities=#{securities.inspect} last_updated=#{last_updated}>"
52
+ end
53
+
54
+ alias :inspect :to_s
55
+
56
+ def <=>(other)
57
+ if other.respond_to? :aba_number
58
+ aba_number <=> other.aba_number
59
+ else
60
+ to_s <=> other.to_s
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ attr_reader :url, :path
67
+
68
+ FEDERAL_URL = 'https://www.fededirectory.frb.org/fpddir.txt'
69
+
70
+ def initialize(url = nil, path = nil)
71
+ @url = url || FEDERAL_URL
72
+ @path = path || File.join(AbaNumbers::DB_PATH, 'fpddir.txt')
73
+ end
74
+
75
+ def file?
76
+ File.file? path
77
+ end
78
+
79
+ def line_count
80
+ File.foreach(path).inject(0) { |c, _| c+1 }
81
+ end
82
+
83
+ def get_file_from_url
84
+ uri = URI url
85
+ https = Net::HTTP.new uri.host, uri.port
86
+
87
+ if uri.scheme == 'https'
88
+ https.use_ssl = true
89
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
90
+ end
91
+
92
+ res = https.request_get uri.request_uri
93
+ File.open(path, 'w') { |f| f.puts res.body }
94
+ end
95
+
96
+ def read_local_file
97
+ data.clear
98
+ File.open(path).each_line do |line|
99
+ line.strip!
100
+ unless line.empty?
101
+ row = Row.new line
102
+ data[row.aba_number] = row
103
+ end
104
+ end
105
+ end
106
+
107
+ def data
108
+ if @data.nil?
109
+ @data = {}
110
+ reload
111
+ end
112
+ @data
113
+ end
114
+
115
+ def [](aba_number)
116
+ data[aba_number.to_s]
117
+ end
118
+
119
+ def needs_getting_file?
120
+ !file? || line_count == 0
121
+ end
122
+
123
+ def reload
124
+ get_file_from_url if needs_getting_file?
125
+ read_local_file
126
+ @loaded = true
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,23 @@
1
+ module AbaNumbers
2
+ module Validation
3
+
4
+ def valid_aba_number?(aba_number)
5
+ aba_number_str = aba_number.to_s.strip
6
+
7
+ return false if aba_number_str.empty?
8
+ return false unless aba_number_str =~ /^\d{9}$/
9
+
10
+ total = 0
11
+ 0.step(9, 3) do |i|
12
+ total += aba_number_str[i..i].to_i * 3
13
+ total += aba_number_str[(i+1)..(i+1)].to_i * 7
14
+ total += aba_number_str[(i+2)..(i+2)].to_i * 1
15
+ end
16
+
17
+ total % 10 == 0
18
+ end
19
+
20
+ module_function :valid_aba_number?
21
+
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module AbaNumbers
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe AbaNumbers::Database do
4
+
5
+ let(:klass) { AbaNumbers::Database }
6
+ let(:tmp_path) { File.join AbaNumbers::TMP_PATH, 'fpddir_fake.txt' }
7
+ let(:db) { klass.new nil, tmp_path }
8
+ let(:line1) { '325170835FBT FSL PT ANBEL FIRST FEDERAL SAVINGS & LOAN OF PA WAPORT ANBELES Y N20060614' }
9
+ let(:line2) { '325180553AK PAC JUBEAU ALASKA PASIFIC BANK AKJUBEAU Y N ' }
10
+ let(:row1) { AbaNumbers::Database::Row.new line1 }
11
+ let(:row2) { AbaNumbers::Database::Row.new line2 }
12
+
13
+ before(:all) { File.open(tmp_path, 'w') { |f| f.puts "#{line1}\n#{line2}" } }
14
+ after(:all) { FileUtils.rm tmp_path }
15
+
16
+ describe 'basic' do
17
+ it { db.url.should == AbaNumbers::Database::FEDERAL_URL }
18
+ it { db.path.should == tmp_path }
19
+ it { db.file?.should be_true }
20
+ it { db.line_count.should == 2 }
21
+ it { db.needs_getting_file?.should be_false }
22
+ it { db.instance_variable_get(:@data).should be_nil }
23
+ end
24
+
25
+ describe 'processing' do
26
+ before(:all) { db.data }
27
+ after(:all) { db.instance_variable_set :@data, nil }
28
+ it { db.data.size.should == 2 }
29
+ it { db.data.size.should == db.line_count }
30
+ it { db.data[row1.aba_number].should == row1 }
31
+ it { db[row2.aba_number].should == row2 }
32
+ end
33
+
34
+ describe 'getting data from federal reserve' do
35
+ if ENV['full_test']
36
+ it 'should download a valid file from the federal reserve database' do
37
+ tmp_path = File.join AbaNumbers::TMP_PATH, 'fpddir.txt'
38
+ FileUtils.rm tmp_path
39
+ db = klass.new nil, tmp_path
40
+ expect { db.get_file_from_url }.to_not raise_error
41
+ db.line_count.should > 0
42
+ end
43
+ else
44
+ pending 'need to run with ENV[\'full_test\'] to test getting an actual data file'
45
+ end
46
+ end
47
+
48
+ describe AbaNumbers::Database::Row do
49
+ describe 'basic #1' do
50
+ it { row1.aba_number.should == '325170835' }
51
+ it { row1.short_name.should == 'FBT FSL PT ANBEL' }
52
+ it { row1.name.should == 'FIRST FEDERAL SAVINGS & LOAN OF PA' }
53
+ it { row1.state.should == 'WA' }
54
+ it { row1.city.should == 'PORT ANBELES' }
55
+ it { row1.funds_transfer.should be_true }
56
+ it { row1.settlement_only.should be_false }
57
+ it { row1.securities.should be_false }
58
+ it { row1.last_updated.to_s.should == '2006-06-14' }
59
+ it { row1.to_s.should == "#<AbaNumbers::Database::Row aba_number=\"325170835\" short_name=\"FBT FSL PT ANBEL\" name=\"FIRST FEDERAL SAVINGS & LOAN OF PA\" state=\"WA\" city=\"PORT ANBELES\" funds_transfer=true settlement_only=false securities=false last_updated=2006-06-14>" }
60
+ it { row1.to_s.should == row1.inspect }
61
+ end
62
+ describe 'basic #2' do
63
+ let(:exp_to_s) { "#<AbaNumbers::Database::Row aba_number=\"325180553\" short_name=\"AK PAC JUBEAU\" name=\"ALASKA PASIFIC BANK\" state=\"AK\" city=\"JUBEAU\" funds_transfer=true settlement_only=false securities=false last_updated=>" }
64
+ let(:other) { mock to_s: exp_to_s }
65
+ it { row2.aba_number.should == '325180553' }
66
+ it { row2.short_name.should == 'AK PAC JUBEAU' }
67
+ it { row2.name.should == 'ALASKA PASIFIC BANK' }
68
+ it { row2.state.should == 'AK' }
69
+ it { row2.city.should == 'JUBEAU' }
70
+ it { row2.funds_transfer.should be_true }
71
+ it { row2.settlement_only.should be_false }
72
+ it { row2.securities.should be_false }
73
+ it { row2.last_updated.should be_nil }
74
+ it { row2.to_s.should == exp_to_s }
75
+ it { row2.should == other }
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,31 @@
1
+ unless Object.const_defined? :SPEC_HELPER_LOADED
2
+
3
+ require 'fileutils'
4
+
5
+ begin
6
+ require 'simplecov'
7
+ SimpleCov.start
8
+ SimpleCov.start do
9
+ add_group 'Libs', 'lib'
10
+ add_group 'Specs', 'spec'
11
+ end
12
+ rescue LoadError
13
+ puts 'SimpleCov not available, skipping coverage...'
14
+ end
15
+
16
+ require 'bundler/setup'
17
+ lib = File.expand_path File.dirname(__FILE__)
18
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
19
+
20
+ require 'aba_numbers'
21
+
22
+ RSpec.configure do |config|
23
+ config.treat_symbols_as_metadata_keys_with_true_values = true
24
+ config.run_all_when_everything_filtered = true
25
+ config.filter_run :focus
26
+ config.order = 'random'
27
+ config.filter_run_excluding :broken => true, :skipped => true
28
+ end
29
+
30
+ Object.const_set :SPEC_HELPER_LOADED, true
31
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe AbaNumbers::Validation do
4
+
5
+ describe 'known valid' do
6
+ %w{ 011501598 011600774 063112728 113093852 114922090 271171674 325272306 }.each do |aba_number|
7
+ it { AbaNumbers::Validation.valid_aba_number?(aba_number).should be_true }
8
+ end
9
+ end
10
+
11
+ describe 'known invalid' do
12
+ %w{ 011501599 011600775 063112729 113093853 114922091 271171675 325272307 }.each do |aba_number|
13
+ it { AbaNumbers::Validation.valid_aba_number?(aba_number).should be_false }
14
+ end
15
+ end
16
+
17
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aba_numbers
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Adrian Madrid
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-03-26 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 47
30
+ segments:
31
+ - 2
32
+ - 8
33
+ - 0
34
+ version: 2.8.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: simplecov
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 1
46
+ segments:
47
+ - 0
48
+ - 7
49
+ - 1
50
+ version: 0.7.1
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: Get a list of Federal Reserve E-Payments Routing Directory
54
+ email:
55
+ - aemadrid@gmail.com
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - aba_numbers.gemspec
69
+ - db/fpddir.txt
70
+ - lib/aba_numbers.rb
71
+ - lib/aba_numbers/database.rb
72
+ - lib/aba_numbers/validation.rb
73
+ - lib/aba_numbers/version.rb
74
+ - spec/database_spec.rb
75
+ - spec/spec_helper.rb
76
+ - spec/validation_spec.rb
77
+ has_rdoc: true
78
+ homepage: https://github.com/NorthPointAdvisors/aba_numbers
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.4.2
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Get a list of Federal Reserve E-Payments Routing Directory from the Federal Reserve Financial Services
111
+ test_files:
112
+ - spec/database_spec.rb
113
+ - spec/spec_helper.rb
114
+ - spec/validation_spec.rb