melissa_data 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -3
- data/lib/melissa_data/config.rb +25 -0
- data/lib/melissa_data/version.rb +1 -1
- data/lib/melissa_data/web_smart/client.rb +9 -0
- data/lib/melissa_data/web_smart/property_api.rb +16 -0
- data/lib/melissa_data/web_smart/xml.rb +72 -0
- data/lib/melissa_data.rb +6 -90
- data/melissa_data.gemspec +3 -3
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 815c3aab597d59d45f0d2b5b6e1090240ca7906c
|
4
|
+
data.tar.gz: 7e250c2c21c8a04507da1572411cc39fceb450b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 597980ef52b375f86ba4fc63890a6bd27435485a325dde170fd4610d682d23c65870e21b9cbb9f791b736242dd199f3a4f8ab3faf19cabc4e4bf8c43acb09839
|
7
|
+
data.tar.gz: bd0b48b5c3b9750628466aa3e1391716ec7080781e3c1a4af0f1778727a9a0cf306fb9563ffe3983a916eee192a37d4841250b69a5d4cd0992ce2d0df31a4156
|
data/README.md
CHANGED
@@ -22,12 +22,13 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
#### Property
|
24
24
|
There is a client included for the property API on Melissa. This requires very little.
|
25
|
-
You will need
|
25
|
+
You will need a `MelissaData Web Smart ID`.
|
26
26
|
Once you have these, you may use the following client. To instantiate a client:
|
27
27
|
|
28
28
|
```ruby
|
29
|
+
irb> MelissaData.web_smart_id = ENV['MELISSA_DATA_WEB_SMART_ID']
|
29
30
|
irb> client = MelissaData::WebSmart::Client.new
|
30
|
-
irb> client.property(some_fips_code, some_apn)
|
31
|
+
irb> client.property(some_fips_code, some_apn)
|
31
32
|
# => property data
|
32
33
|
```
|
33
34
|
|
@@ -226,6 +227,23 @@ Data comes in the following form:
|
|
226
227
|
}
|
227
228
|
```
|
228
229
|
|
230
|
+
## Configuration
|
231
|
+
|
232
|
+
There are two ways to configure the gem.
|
233
|
+
|
234
|
+
### Block configuration
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
MelissaData.configure do |config|
|
238
|
+
config.web_smart_id = ENV['MELISSA_DATA_WEB_SMART_ID']
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
### One-liner
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
MelissaData.web_smart_id = ENV['MELISSA_DATA_WEB_SMART_ID']
|
246
|
+
```
|
229
247
|
|
230
248
|
## Development
|
231
249
|
|
@@ -241,4 +259,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
|
|
241
259
|
## License
|
242
260
|
|
243
261
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
244
|
-
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MelissaData
|
2
|
+
module Config
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(self)
|
5
|
+
end
|
6
|
+
|
7
|
+
# @!attribute web_smart_id
|
8
|
+
# @return [String] web smart id to be used
|
9
|
+
attr_accessor :web_smart_id
|
10
|
+
|
11
|
+
# Configures web_smart_id and property_api_url
|
12
|
+
# Usage example:
|
13
|
+
# MelissaData.configure do |config|
|
14
|
+
# config.web_smart_id = ENV['MELISSA_DATA_WEB_SMART_ID']
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# Alternate way:
|
18
|
+
# MelissaData.web_smart_id = ENV['MELISSA_DATA_WEB_SMART_ID']
|
19
|
+
#
|
20
|
+
# @param <api_key> [String] web smart id to use
|
21
|
+
def configure
|
22
|
+
yield self if block_given?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/melissa_data/version.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module MelissaData
|
5
|
+
module WebSmart
|
6
|
+
class PropertyAPI
|
7
|
+
def property(fips, apn)
|
8
|
+
resp = RestClient.get('https://property.melissadata.net/v3/REST/Service.svc/doLookup',
|
9
|
+
{ params: { id: MelissaData.web_smart_id,
|
10
|
+
fips: fips,
|
11
|
+
apn: apn } })
|
12
|
+
PropertyXMLParser.new(Nokogiri::XML(resp)).parse
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module MelissaData
|
2
|
+
module WebSmart
|
3
|
+
class XMLParser
|
4
|
+
attr_accessor :xml_document
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
@xml_document = xml
|
8
|
+
end
|
9
|
+
|
10
|
+
def children?(xml_node)
|
11
|
+
xml_node.children.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def viperize_hash hash
|
15
|
+
hash.map { |key, value| { viperize(key.to_s) => value } }.reduce(:merge)
|
16
|
+
end
|
17
|
+
|
18
|
+
def viperize(string)
|
19
|
+
word = string.to_s.dup
|
20
|
+
word.gsub!(/::/, '/')
|
21
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
22
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
23
|
+
word.tr!("-", "_")
|
24
|
+
word.downcase!
|
25
|
+
word.to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PropertyXMLParser < XMLParser
|
30
|
+
def parse
|
31
|
+
parsed_hash = {}
|
32
|
+
if expected_retrieved?
|
33
|
+
retrieved_fields.each_with_index { |f, i| parsed_hash[f] = { data: field_details[i] } }
|
34
|
+
parsed_hash.keys.each { |k| parsed_hash[k] = build_subdictionary(parsed_hash[k][:data]) }
|
35
|
+
viperize_hash(parsed_hash)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def field_details
|
40
|
+
record_node.children.map(&:children)
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_subdictionary(xml_vals)
|
44
|
+
keys = xml_vals.map(&:name)
|
45
|
+
vals = xml_vals.map { |v| v.children.first.text unless children? v }
|
46
|
+
viperize_hash(keys.zip(vals).to_h)
|
47
|
+
end
|
48
|
+
|
49
|
+
def expected_fields
|
50
|
+
[ "Building", "CurrentDeed", "CurrentSale", "Lot", "Owner",
|
51
|
+
"OwnerAddress", "Parcel", "ParsedPropertyAddress", "PriorSale",
|
52
|
+
"PropertyAddress", "RecordID", "Result", "SquareFootage", "Values"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def expected_fields?(fields)
|
56
|
+
expected_fields == fields.sort
|
57
|
+
end
|
58
|
+
|
59
|
+
def record_node
|
60
|
+
xml_document.children.first.children.last # its just how they structure it..
|
61
|
+
end
|
62
|
+
|
63
|
+
def retrieved_fields
|
64
|
+
record_node.children.map(&:name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def expected_retrieved?
|
68
|
+
expected_fields?(retrieved_fields)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/melissa_data.rb
CHANGED
@@ -1,96 +1,12 @@
|
|
1
1
|
require "melissa_data/version"
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require "melissa_data/web_smart/xml"
|
3
|
+
require "melissa_data/web_smart/client"
|
4
|
+
require "melissa_data/web_smart/property_api"
|
5
|
+
require "melissa_data/config"
|
6
|
+
|
5
7
|
require 'rest-client'
|
6
8
|
require 'nokogiri'
|
7
9
|
|
8
10
|
module MelissaData
|
9
|
-
|
10
|
-
class PropertyAPI
|
11
|
-
def property(fips, apn)
|
12
|
-
url = 'https://property.melissadata.net/v3/REST/Service.svc/doLookup'
|
13
|
-
resp = RestClient.get(url,
|
14
|
-
{ params: { id: ENV['MELISSA_DATA_WEB_SMART_ID'],
|
15
|
-
fips: fips,
|
16
|
-
apn: apn } })
|
17
|
-
PropertyXMLParser.new(Nokogiri::XML(resp)).parse
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class XMLParser
|
22
|
-
attr_accessor :xml_document
|
23
|
-
|
24
|
-
def initialize(xml)
|
25
|
-
@xml_document = xml
|
26
|
-
end
|
27
|
-
|
28
|
-
def children?(xml_node)
|
29
|
-
xml_node.children.empty?
|
30
|
-
end
|
31
|
-
|
32
|
-
def viperize_hash hash
|
33
|
-
hash.map { |key, value| { viperize(key.to_s) => value } }.reduce(:merge)
|
34
|
-
end
|
35
|
-
|
36
|
-
def viperize(string)
|
37
|
-
word = string.to_s.dup
|
38
|
-
word.gsub!(/::/, '/')
|
39
|
-
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
40
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
41
|
-
word.tr!("-", "_")
|
42
|
-
word.downcase!
|
43
|
-
word.to_sym
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
class PropertyXMLParser < XMLParser
|
48
|
-
def parse
|
49
|
-
parsed_hash = {}
|
50
|
-
if expected_retrieved?
|
51
|
-
retrieved_fields.each_with_index { |f, i| parsed_hash[f] = { data: field_details[i] } }
|
52
|
-
parsed_hash.keys.each { |k| parsed_hash[k] = build_subdictionary(parsed_hash[k][:data]) }
|
53
|
-
viperize_hash(parsed_hash)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def field_details
|
58
|
-
record_node.children.map { |n| n.children }
|
59
|
-
end
|
60
|
-
|
61
|
-
def build_subdictionary(xml_vals)
|
62
|
-
keys = xml_vals.map(&:name)
|
63
|
-
vals = xml_vals.map { |v| v.children.first.text unless children? v }
|
64
|
-
viperize_hash(keys.zip(vals).to_h)
|
65
|
-
end
|
66
|
-
|
67
|
-
def expected_fields
|
68
|
-
[ "RecordID", "Result", "Parcel", "PropertyAddress", "ParsedPropertyAddress",
|
69
|
-
"Owner", "OwnerAddress", "Values", "CurrentSale", "CurrentDeed", "PriorSale",
|
70
|
-
"Lot", "SquareFootage", "Building" ].sort
|
71
|
-
end
|
72
|
-
|
73
|
-
def expected_fields?(fields)
|
74
|
-
expected_fields == fields.sort
|
75
|
-
end
|
76
|
-
|
77
|
-
def record_node
|
78
|
-
xml_document.children.first.children.last # its just how they structure it..
|
79
|
-
end
|
80
|
-
|
81
|
-
def retrieved_fields
|
82
|
-
record_node.children.map { |n| n.name }
|
83
|
-
end
|
84
|
-
|
85
|
-
def expected_retrieved?
|
86
|
-
expected_fields?(retrieved_fields)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class Client
|
91
|
-
def property(fips, apn)
|
92
|
-
MelissaData::WebSmart::PropertyAPI.new.property(fips, apn)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
11
|
+
include MelissaData::Config
|
96
12
|
end
|
data/melissa_data.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'melissa_data/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "melissa_data"
|
8
8
|
spec.version = MelissaData::VERSION
|
9
|
-
spec.authors = ["Robert Grayson"]
|
10
|
-
spec.email = ["bobbygrayson@gmail.com"]
|
9
|
+
spec.authors = ["Robert Grayson", "Jonah Ruiz"]
|
10
|
+
spec.email = ["bobbygrayson@gmail.com", "jonah@pixelhipsters.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{A simple interface to Melissa Data's Web Smart Property API}
|
13
13
|
spec.description = %q{A simple interface to Melissa Data's Web Smart Property API}
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.bindir = "exe"
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
-
|
21
|
+
|
22
22
|
spec.add_runtime_dependency "nokogiri"
|
23
23
|
spec.add_runtime_dependency "rest-client"
|
24
24
|
|
metadata
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: melissa_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Grayson
|
8
|
+
- Jonah Ruiz
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
@@ -111,6 +112,7 @@ dependencies:
|
|
111
112
|
description: A simple interface to Melissa Data's Web Smart Property API
|
112
113
|
email:
|
113
114
|
- bobbygrayson@gmail.com
|
115
|
+
- jonah@pixelhipsters.com
|
114
116
|
executables: []
|
115
117
|
extensions: []
|
116
118
|
extra_rdoc_files: []
|
@@ -126,7 +128,11 @@ files:
|
|
126
128
|
- bin/console
|
127
129
|
- bin/setup
|
128
130
|
- lib/melissa_data.rb
|
131
|
+
- lib/melissa_data/config.rb
|
129
132
|
- lib/melissa_data/version.rb
|
133
|
+
- lib/melissa_data/web_smart/client.rb
|
134
|
+
- lib/melissa_data/web_smart/property_api.rb
|
135
|
+
- lib/melissa_data/web_smart/xml.rb
|
130
136
|
- melissa_data.gemspec
|
131
137
|
homepage: http://github.com/cometaworks/melissa_data
|
132
138
|
licenses:
|
@@ -148,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
154
|
version: '0'
|
149
155
|
requirements: []
|
150
156
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.4.
|
157
|
+
rubygems_version: 2.4.5
|
152
158
|
signing_key:
|
153
159
|
specification_version: 4
|
154
160
|
summary: A simple interface to Melissa Data's Web Smart Property API
|