ncua 0.5.0 → 0.6.0

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: d80b3ab492107fa4574336a527522217465ac829
4
- data.tar.gz: 89b3e21b98a1feaa85d3555d4fe7a3a7b01535dc
3
+ metadata.gz: ddc3ec546e01ed562477979e46f561a9d2d92a35
4
+ data.tar.gz: 083c148ab6e1d1a38018095dc8356b6be59d1a8a
5
5
  SHA512:
6
- metadata.gz: 7f1ece268d4b81aebc6b6ac37654aa67dd1b5c2b0772caa7258b9aaa9bd87a2174f3fee57e2c838e61fcec4b8348762c6826e8ca29634216f0aebad534872457
7
- data.tar.gz: adead7d121f4afa6b779b1e8fab4890d90e0423ec508b7156e30fc39e7e984e2d677f3d09ea8858dfd0b4cd711269231900e91231bfb7f1bef58018f7e601e60
6
+ metadata.gz: ebe48264ba4e9aee02ac366b7256a73f8654406c70ba785da3076c2b29acc02c2b0955bb9f072367ff3b867e1e31872d326ae4ba0b7db84b35f433dd921e4ace
7
+ data.tar.gz: b68cff3ab80ea08baac13ac9e8a8d09221414b0095dfa46ddb83845473bb3f7bc2f090b2e555fb16466738754ed670cdb2d092411c3071c0f2760777f6c83dee
data/.gitignore CHANGED
@@ -8,3 +8,4 @@ ncua-*.gem
8
8
  /pkg/
9
9
  /spec/reports/
10
10
  /tmp/
11
+ /private/
data/README.md CHANGED
@@ -28,44 +28,81 @@ Or install it yourself as:
28
28
 
29
29
  Currently all of our features are namespaced under the `NCUA` module.
30
30
 
31
- The NCUA lets you find a Credit Union office by its name, charter number, or within an address:
31
+ The NCUA lets you find a Credit Union Office by its name, charter number, or within an address:
32
32
 
33
33
  ```ruby
34
- credit_unions = NCUA.find_by_name('Federal') #=> [NCUA::CreditUnion, ... ]
34
+ credit_unions = NCUA.find_office_by_name('Federal') #=> [NCUA::CreditUnion::Office, ... ]
35
35
  ```
36
36
 
37
- You can `find_by` `name`, `address`, `charter_number`. Searching by address takes an optional radius argument to limit the scope of the address query (units are in miles):
37
+ You can also find an office by `name`, `address`, `charter_number`. Searching by address takes an optional radius argument to limit the scope of the address query (units are in miles):
38
38
  ```ruby
39
- credit_unions = NCUA.find_by_charter_number(12345) #=> [NCUA::CreditUnion, ... ]
39
+ credit_unions = NCUA.find_office_by_charter_number(12345) #=> [NCUA::CreditUnion::Office, ... ]
40
40
 
41
- credit_unions = NCUA.find_by_address("125 Main St., Anywhere, CT", radius: 50) #=> [NCUA::CreditUnion, ... ]
42
-
41
+ credit_unions = NCUA.find_office_by_address("125 Main St., Anywhere, CT", radius: 50) #=> [NCUA::CreditUnion::Office, ... ]
43
42
  ```
44
43
 
45
- Right now, an `NCUA::CreditUnion` has all of the following getters:
46
-
47
- | ----------------------------- | ------------------------------------------------------------- |
48
- | Method | Explanation |
49
- | ----------------------------- | ------------------------------------------------------------- |
50
- | `name` | The Credit Union's Name |
51
- | `long` | The Longitude of the Credit Union |
52
- | `lat` | The Latitude of the Credit Union |
53
- | `site_name` | The name of the Credit Union office or branch |
54
- | `charter_number` | The Credit Union's Charter Number |
55
- | `city` | The Credit Union's City |
56
- | `country` | The Credit Union's Country |
57
- | `main_office?` | Whether the Credit Union office is the Main Office |
58
- | `phone` | The Credit Union's phone number |
59
- | `site_functions` | The Credit Union's Site functions.\* |
60
- | `site_id` | The Credit Union's Site ID |
61
- | `state` | The Credit Union's State |
62
- | `url` | The Credit Union's Url |
63
- | `zip` | The Credit Union's Zip Code |
64
- | `distance_from_query_address` | The Distance between the queried address and the Credit Union |
65
- | `street` | The Credit Union's Street address |
66
- | ----------------------------- | ------------------------------------------------------------- |
67
-
68
- \*Currently these are limited to `Member Services`, `Drive Through` and `ATM`
44
+ Right now, an `NCUA::CreditUnion::Office` has all of the following getters:
45
+
46
+ ```
47
+ | --------------------------- | ------------------------------------------------------------- |
48
+ | Method | Explanation |
49
+ | --------------------------- | ------------------------------------------------------------- |
50
+ | name | The Credit Union's Name |
51
+ | long | The Longitude of the Credit Union |
52
+ | lat | The Latitude of the Credit Union |
53
+ | site_name | The name of the Credit Union office or branch |
54
+ | charter_number | The Credit Union's Charter Number |
55
+ | city | The Credit Union's City |
56
+ | country | The Credit Union's Country |
57
+ | main_office? | Whether the Credit Union office is the Main Office |
58
+ | phone | The Credit Union's phone number |
59
+ | site_functions | The Credit Union's Site functions.* |
60
+ | site_id | The Credit Union's Site ID |
61
+ | state | The Credit Union's State |
62
+ | url | The Credit Union's Url |
63
+ | zip | The Credit Union's Zip Code |
64
+ | distance_from_query_address | The Distance between the queried address and the Credit Union |
65
+ | street | The Credit Union's Street address |
66
+ | --------------------------- | ------------------------------------------------------------- |
67
+
68
+ *Currently these are limited to `Member Services`, `Drive Through` and `ATM`
69
+ ```
70
+
71
+ `NCUA::CreditUnion::Office` also exposes a `#details` method. This scrapes the NCUA's show page for a particular credit union, and returns an `NCUA::CreditUnion::Details` object. This object contains the details of a particular Credit Union, instead of a particular office location.
72
+
73
+ Keep in mind, this _scrapes_ data from html, so this might break regularly.
74
+
75
+ Right now, an `NCUA::CreditUnion::Details` object has the following getters:
76
+ ```
77
+ | field | description |
78
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------ |
79
+ | credit_union_name | The Credit Union's name |
80
+ | charter_number | The Credit Union's NCUA charter number |
81
+ | credit_union_type | The Type of Credit Union (Either Federal Credit Union [FCU] or Federally Insured State Credit Union [FISCU]) |
82
+ | active? | Whether the Credit Union is active or not |
83
+ | corporate_credit_union? | Whether the Credit Union is a corporate credit union or not |
84
+ | credit_union_charter_year | The year the Credit Union was chartered |
85
+ | current_charter_issue_date | The date the current charter was issued |
86
+ | date_insured | The date that the Credit Union was insured as of |
87
+ | charter_state | The charter state of the Credit Union |
88
+ | region | The Credit Union's region |
89
+ | field_of_membership_type | The Credit Union's field of membership type |
90
+ | low_income_designation? | Whether the Credit Union has low income designation |
91
+ | member_of_fhlb? | Whether the Credit Union is a member of the Federal Home Loan Bank System |
92
+ | assets | The total assets of the Credit Union, as a floating point decimal |
93
+ | peer_group | The Credit Union's Peer Group |
94
+ | number_of_members | The Credit Union's number of Members |
95
+ | address | The street address of the Credit Union |
96
+ | city_state_zip_code | The City, State and Zip code of the Credit Union |
97
+ | country | The Country of the Credit Union |
98
+ | county | The County of the Credit Union |
99
+ | phone | The Phone number of the Credit Union |
100
+ | website | The Website of the Credit Union |
101
+ | ceo_or_manager | The name of the CEO or Manager of the Credit Union |
102
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------ |
103
+ ```
104
+
105
+ You can also scrape this directly from the NCUA module by calling `NCUA.find_credit_union(charter_number)`
69
106
 
70
107
  ## Contributing
71
108
 
@@ -2,23 +2,28 @@ require 'httparty'
2
2
  require 'nokogiri'
3
3
  require 'ncua/version'
4
4
  require 'ncua/client'
5
- require 'ncua/record'
6
- require 'ncua/credit_union'
7
- require 'ncua/scraper'
5
+ require 'ncua/credit_union/record'
6
+ require 'ncua/credit_union/office'
7
+ require 'ncua/credit_union/details'
8
+ require 'ncua/credit_union/scraper'
8
9
 
9
10
  module NCUA
10
- def self.find_by_address(address, opts={radius: 100})
11
+ def self.find_office_by_address(address, opts={radius: 100})
11
12
  resp = Client.new.find_credit_union_by_address(address, opts[:radius])
12
- resp["list"].map { |result| CreditUnion.new(result) }
13
+ resp["list"].map { |result| CreditUnion::Office.new(result) }
13
14
  end
14
15
 
15
- def self.find_by_name(name)
16
+ def self.find_office_by_name(name)
16
17
  resp = Client.new.find_credit_union_by_name(name)
17
- resp["list"].map { |result| CreditUnion.new(result) }
18
+ resp["list"].map { |result| CreditUnion::Office.new(result) }
18
19
  end
19
20
 
20
- def self.find_by_charter_number(charter_number)
21
+ def self.find_office_by_charter_number(charter_number)
21
22
  resp = Client.new.find_credit_union_by_charter_number(charter_number)
22
- resp["list"].map { |result| CreditUnion.new(result) }
23
+ resp["list"].map { |result| CreditUnion::Office.new(result) }
24
+ end
25
+
26
+ def self.find_credit_union(charter_number)
27
+ CreditUnion::Details.new(CreditUnion::Scraper.new(charter_number).scrape!)
23
28
  end
24
29
  end
@@ -0,0 +1,29 @@
1
+ module NCUA
2
+ module CreditUnion
3
+ class Details < Record
4
+ field :credit_union_name
5
+ field :charter_number
6
+ field :credit_union_type
7
+ field(:active?, :credit_union_status) { |value| value == "Active" }
8
+ field(:corporate_credit_union?, :corporate_credit_union) { |value| value == "Yes" }
9
+ field :credit_union_charter_year
10
+ field(:current_charter_issue_date) { |value| Date.strptime(value, '%m/%d/%Y') }
11
+ field(:date_insured) { |value| Date.strptime(value, '%m/%d/%Y') }
12
+ field :charter_state
13
+ field :region
14
+ field :field_of_membership_type
15
+ field(:low_income_designation?, :low_income_designation) { |value| value == "Yes" }
16
+ field(:member_of_fhlb?, :member_of_fhlb) { |value| value == "Yes" }
17
+ field(:assets) { |value| value.gsub(/[$,]/,"").to_f }
18
+ field :peer_group
19
+ field(:number_of_members) { |value| value.gsub(",","").to_i }
20
+ field :address
21
+ field :city_state_zip_code
22
+ field :country
23
+ field :county
24
+ field :phone
25
+ field :website
26
+ field :ceo_or_manager
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ module NCUA
2
+ module CreditUnion
3
+ class Office < Record
4
+ field :name, 'CU_NAME'
5
+ field :long, 'AddressLongitude'
6
+ field :lat, 'AddressLatitude'
7
+ field :site_name, 'CU_SITENAME'
8
+ field :charter_number, 'CU_NUMBER'
9
+ field :city, 'City'
10
+ field :country, 'Country'
11
+ field :main_office?, 'IsMainOffice'
12
+ field :phone, 'Phone'
13
+ field(:site_functions, 'SiteFunctions') { |value| value.split(";") }
14
+ field :site_id, 'SiteId'
15
+ field :state, 'State'
16
+ field :url, 'URL'
17
+ field :zip, 'Zipcode'
18
+ field(:distance_from_query_address, 'distance') { |value| nil if value < 0 }
19
+ field(:street, 'Street', &:strip)
20
+
21
+ def details
22
+ @details ||= Details.new(get_details!)
23
+ end
24
+
25
+ private
26
+
27
+ def get_details!
28
+ @scraped_attributes ||= Scraper.new(charter_number).scrape!
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ module NCUA
2
+ module CreditUnion
3
+ class Record
4
+ def initialize(attributes)
5
+ @attributes = attributes
6
+ @attributes.freeze
7
+ end
8
+
9
+ attr_reader :attributes
10
+
11
+ def self.field(method_name, response_key=method_name, &munger)
12
+ munger ||= lambda { |x| x }
13
+ define_method(method_name) {
14
+ if response_key.is_a? Symbol
15
+ value = attributes[response_key]
16
+ else
17
+ value = attributes[response_key.to_s]
18
+ end
19
+ value && munger.call(value)
20
+ }
21
+ end
22
+
23
+ def self.int_field(method_name, response_key=method_name)
24
+ field(method_name, response_key, &:to_i)
25
+ end
26
+
27
+ def self.date_field(method_name, response_key=method_name)
28
+ field(method_name, response_key) { |value|
29
+ Date.parse(value)
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ module NCUA
2
+ module CreditUnion
3
+ class Scraper
4
+ #This bit is as brittle as glass, as coupled as conjoined twins, and as stinky as bad cheese
5
+ include HTTParty
6
+
7
+ base_uri 'http://mapping.ncua.gov'
8
+ def initialize(charter_number)
9
+ @charter_number = charter_number
10
+ end
11
+
12
+ def scrape!
13
+ Hash[html_doc.at_css("table#MainContent_newDetails").css("tr").map do |tr|
14
+ if tr.at_css("td.dvHeader") && tr.at_css("td.dvHeader + td")
15
+ [clean_header(tr.at_css("td.dvHeader").text), clean_value(tr.at_css("td.dvHeader + td").text)]
16
+ end
17
+ end]
18
+ end
19
+
20
+ private
21
+
22
+ def clean_header(text)
23
+ text.gsub(/[,:]/,"").
24
+ gsub("/", " or ").
25
+ gsub(" ","_").
26
+ downcase.
27
+ to_sym
28
+ end
29
+
30
+ def clean_value(text)
31
+ text.gsub(/[\n\r]/,"").strip
32
+ end
33
+
34
+ def html_doc
35
+ Nokogiri::HTML(request.body)
36
+ end
37
+
38
+ def request
39
+ self.class.get(endpoint, query: {
40
+ "ID" => @charter_number
41
+ })
42
+ end
43
+
44
+ def endpoint
45
+ '/SingleResult.aspx'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module NCUA
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_runtime_dependency "httparty", "~> 0.13"
24
- spec.add_runtime_dependency "nokogiri", "~> 1.6.0"
24
+ spec.add_runtime_dependency 'nokogiri', '~> 1.6', '>= 1.6.0'
25
25
  spec.add_development_dependency "bundler", "~> 1.10"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
27
  spec.add_development_dependency "rspec", "~> 3.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ncua
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Reznick
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-09 00:00:00.000000000 Z
11
+ date: 2015-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -29,6 +29,9 @@ dependencies:
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ - - ">="
32
35
  - !ruby/object:Gem::Version
33
36
  version: 1.6.0
34
37
  type: :runtime
@@ -36,6 +39,9 @@ dependencies:
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.6'
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
46
  version: 1.6.0
41
47
  - !ruby/object:Gem::Dependency
@@ -98,9 +104,10 @@ files:
98
104
  - bin/setup
99
105
  - lib/ncua.rb
100
106
  - lib/ncua/client.rb
101
- - lib/ncua/credit_union.rb
102
- - lib/ncua/record.rb
103
- - lib/ncua/scraper.rb
107
+ - lib/ncua/credit_union/details.rb
108
+ - lib/ncua/credit_union/office.rb
109
+ - lib/ncua/credit_union/record.rb
110
+ - lib/ncua/credit_union/scraper.rb
104
111
  - lib/ncua/version.rb
105
112
  - ncua.gemspec
106
113
  homepage: https://github.com/ContinuityControl/ncua
@@ -1,28 +0,0 @@
1
- module NCUA
2
- class CreditUnion < Record
3
- field :name, 'CU_NAME'
4
- field :long, 'AddressLongitude'
5
- field :lat, 'AddressLatitude'
6
- field :site_name, 'CU_SITENAME'
7
- field :charter_number, 'CU_NUMBER'
8
- field :city, 'City'
9
- field :country, 'Country'
10
- field :main_office?, 'IsMainOffice'
11
- field :phone, 'Phone'
12
- field(:site_functions, 'SiteFunctions') { |value| value.split(";") }
13
- field :site_id, 'SiteId'
14
- field :state, 'State'
15
- field :url, 'URL'
16
- field :zip, 'Zipcode'
17
- field(:distance_from_query_address, 'distance') { |value| nil if value < 0 }
18
- field(:street, 'Street', &:strip)
19
-
20
- def munge!
21
- @scraped_attributes ||= Scraper.new(charter_number).scrape!
22
- end
23
-
24
- def additional_attributes
25
- @scraped_attributes
26
- end
27
- end
28
- end
@@ -1,34 +0,0 @@
1
- module NCUA
2
- class Record
3
- def initialize(attributes)
4
- @attributes = attributes
5
- @attributes.freeze
6
- end
7
-
8
- attr_reader :attributes
9
-
10
- def self.field(method_name, response_key=method_name, &munger)
11
- munger ||= lambda { |x| x }
12
- define_method(method_name) {
13
- value = attributes[response_key.to_s]
14
- value && munger.call(value)
15
- }
16
- end
17
-
18
- def self.int_field(method_name, response_key=method_name)
19
- field(method_name, response_key, &:to_i)
20
- end
21
-
22
- def self.currency_field(method_name, response_key=method_name)
23
- field(method_name, response_key) { |value|
24
- value.to_f * 1000
25
- }
26
- end
27
-
28
- def self.date_field(method_name, response_key=method_name)
29
- field(method_name, response_key) { |value|
30
- Date.parse(value)
31
- }
32
- end
33
- end
34
- end
@@ -1,47 +0,0 @@
1
- module NCUA
2
- class Scraper
3
- #This bit is as brittle as glass, as coupled as conjoined twins, and as stinky as bad cheese
4
- include HTTParty
5
-
6
- base_uri 'http://mapping.ncua.gov'
7
- def initialize(charter_number)
8
- @charter_number = charter_number
9
- end
10
-
11
- def scrape!
12
- Hash[html_doc.at_css("table#MainContent_newDetails").css("tr").map do |tr|
13
- if tr.at_css("td.dvHeader") && tr.at_css("td.dvHeader + td")
14
- [clean_header(tr.at_css("td.dvHeader").text), clean_value(tr.at_css("td.dvHeader + td").text)]
15
- end
16
- end]
17
- end
18
-
19
- private
20
-
21
- def clean_header(text)
22
- text.gsub(/[,:]/,"").
23
- gsub("/", " or ").
24
- gsub(" ","_").
25
- downcase.
26
- to_sym
27
- end
28
-
29
- def clean_value(text)
30
- text.gsub(/[\n\r]/,"").strip
31
- end
32
-
33
- def html_doc
34
- Nokogiri::HTML(request.body)
35
- end
36
-
37
- def request
38
- self.class.get(endpoint, query: {
39
- "ID" => @charter_number
40
- })
41
- end
42
-
43
- def endpoint
44
- '/SingleResult.aspx'
45
- end
46
- end
47
- end