eaternet 0.4.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/eaternet.gemspec +1 -1
- data/lib/eaternet/agencies/snhd.rb +77 -98
- data/lib/eaternet/agencies/snhd_prototype.rb +103 -0
- data/lib/eaternet/version.rb +1 -1
- data/lib/eaternet.rb +0 -2
- data/test/eaternet/agencies/snhd_prototype_test.rb +128 -0
- data/test/eaternet/agencies/snhd_test.rb +28 -81
- metadata +8 -9
- data/lib/eaternet/agencies/snhd_lives.rb +0 -106
- data/test/eaternet/agencies/snhd_lives_test.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4593dfcf3a89703992a04487b287240043dfd3d4
|
4
|
+
data.tar.gz: 1b766e1829a7b3bb3c79ea2a67b628bd6a0a9c78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b3f69b0b5b9ee069e413f9fa773e41be46fb2ec69d48e62b945d9a74441050e636cced72de54797fe79a4d9d39dce9fd5597f08c0d79e03ec05a75645181816
|
7
|
+
data.tar.gz: 80e086a93cb536589a9756025b1712dee785a2914649707ad4f107566c74702fab75c4aff53c1801770ec6a3bb4450c8bd4435a565459bdbdde3059ee24f744f
|
data/eaternet.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'vcr'
|
30
30
|
spec.add_development_dependency 'webmock'
|
31
31
|
|
32
|
-
spec.add_runtime_dependency 'activemodel', '
|
32
|
+
spec.add_runtime_dependency 'activemodel', '>= 3.2.21'
|
33
33
|
spec.add_runtime_dependency 'rubyzip'
|
34
34
|
spec.add_runtime_dependency 'httparty'
|
35
35
|
end
|
@@ -1,126 +1,105 @@
|
|
1
|
-
require '
|
2
|
-
require 'eaternet/
|
3
|
-
require 'eaternet/prototype'
|
1
|
+
require 'date'
|
2
|
+
require 'eaternet/loggable'
|
4
3
|
require 'eaternet/util'
|
4
|
+
require 'eaternet/agencies/snhd_prototype'
|
5
5
|
|
6
6
|
module Eaternet
|
7
7
|
module Agencies
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# agency = Eaternet::Snhd.new
|
16
|
-
# agency.businesses
|
17
|
-
# .select { |biz| biz.city == 'Las Vegas' }
|
18
|
-
# .each { |biz| puts biz.name }
|
19
|
-
#
|
20
|
-
# The SNHD makes their restaurant inspection data available via a zip file
|
21
|
-
# for download. The file contains several Mysql tables converted to CSV.
|
22
|
-
# And so, this is an example for how to code adapters for other agencies
|
23
|
-
# which publish their data in a similar way.
|
24
|
-
#
|
25
|
-
# This code downloads the latest zip file, extracts it, parses the csv,
|
26
|
-
# and provides enumerators of Businesses, Inspections, Violations, and
|
27
|
-
# ViolationKinds. (These are specified in the
|
28
|
-
# Eaternet::Prototype module.)
|
29
|
-
#
|
30
|
-
# SNHD's CSV format seems to be non-standard, e.g. using the double-quote
|
31
|
-
# character in fields without escaping it. We need to find out what their
|
32
|
-
# quote character actually is. In the meantime, the files can be parsed by
|
33
|
-
# setting the quote character to something else that doesn't appear in the
|
34
|
-
# text, such as a pipe symbol.
|
35
|
-
#
|
36
|
-
# @see http://southernnevadahealthdistrict.org/restaurants/inspect-downloads.php
|
37
|
-
# The SNHD Developer information page
|
38
|
-
# @see Eaternet::Prototype Framework module
|
39
|
-
class Snhd
|
40
|
-
include Eaternet::Prototype::AbstractAdapter
|
8
|
+
class Snhd < Eaternet::Lives_1_0::Adapter
|
9
|
+
include Eaternet::Loggable
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@prototype = Eaternet::Agencies::SnhdPrototype.new
|
13
|
+
end
|
41
14
|
|
42
|
-
# (see Eaternet::Prototype::AbstractAdapter#businesses)
|
43
15
|
def businesses
|
44
|
-
|
45
|
-
|
46
|
-
orig_key: row['permit_number'],
|
47
|
-
name: row['restaurant_name'],
|
48
|
-
address: row['address'],
|
49
|
-
city: row['city_name'],
|
50
|
-
zipcode: row['zip_code']
|
51
|
-
)
|
52
|
-
end
|
16
|
+
@prototype.businesses
|
17
|
+
.map { |proto| try_to_create_business(proto) }
|
53
18
|
end
|
54
19
|
|
55
|
-
# (see Eaternet::Prototype::AbstractAdapter#inspections)
|
56
20
|
def inspections
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
score: row['inspection_grade'],
|
67
|
-
demerits: row['inspection_demerits'],
|
68
|
-
date: row['inspection_date'],
|
69
|
-
violations: violations
|
70
|
-
)
|
21
|
+
@prototype.inspections
|
22
|
+
.map { |proto| try_to_create_inspection(proto) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def try_to_create_business(proto)
|
26
|
+
business(proto)
|
27
|
+
rescue ArgumentError => e
|
28
|
+
logger.warn('SNHD LIVES adapter') do
|
29
|
+
"Could not create a LIVES Business from #{proto.inspect}: #{e}"
|
71
30
|
end
|
31
|
+
nil
|
72
32
|
end
|
73
33
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
inspection_id: row['inspection_id'],
|
80
|
-
violation_kind_id: row['inspection_violation']
|
81
|
-
)
|
34
|
+
def try_to_create_inspection(proto)
|
35
|
+
inspection(proto)
|
36
|
+
rescue ArgumentError => e
|
37
|
+
logger.warn('SNHD LIVES adapter') do
|
38
|
+
"Could not create a LIVES Inspection from #{proto.inspect}: #{e}"
|
82
39
|
end
|
40
|
+
nil
|
83
41
|
end
|
84
42
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
description: row['violation_description']
|
94
|
-
)
|
43
|
+
def business(proto)
|
44
|
+
Eaternet::Lives_1_0::Business.new do |b|
|
45
|
+
b.business_id = proto.orig_key
|
46
|
+
b.name = proto.name
|
47
|
+
b.address = proto.address
|
48
|
+
b.city = proto.city
|
49
|
+
b.postal_code = proto.zipcode
|
50
|
+
b.state = 'NV'
|
95
51
|
end
|
96
52
|
end
|
97
53
|
|
98
|
-
|
54
|
+
def inspection(proto)
|
55
|
+
Eaternet::Lives_1_0::Inspection.new do |i|
|
56
|
+
i.business_id = proto.business_orig_key
|
57
|
+
i.score = proto.demerits.nil? ? nil : 100 - proto.demerits.to_i
|
58
|
+
i.date = Date.parse(proto.date)
|
59
|
+
end
|
60
|
+
end
|
99
61
|
|
100
|
-
def
|
101
|
-
|
62
|
+
def violations
|
63
|
+
@violations ||= _violations
|
102
64
|
end
|
103
65
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
66
|
+
def feed_info
|
67
|
+
Eaternet::Lives_1_0::FeedInfo.new do |fi|
|
68
|
+
fi.feed_date = Date.today
|
69
|
+
fi.feed_version = '1.0'
|
70
|
+
fi.municipality_name = 'Southern Nevada'
|
71
|
+
fi.municipality_url = 'http://southernnevadahealthdistrict.org/restaurants/index.php'
|
72
|
+
fi.contact_email = 'environmentalhealth@snhdmail.org'
|
73
|
+
end
|
109
74
|
end
|
110
75
|
|
111
|
-
def
|
112
|
-
|
113
|
-
file.readline # Skip the non-standard header line
|
114
|
-
CSV.new(
|
115
|
-
file,
|
116
|
-
headers: headers,
|
117
|
-
col_sep: SnhdConfig::COLUMN_SEPARATOR,
|
118
|
-
quote_char: SnhdConfig::QUOTE_CHARACTER
|
119
|
-
)
|
76
|
+
def legends
|
77
|
+
[]
|
120
78
|
end
|
121
79
|
|
122
|
-
def
|
123
|
-
|
80
|
+
def _violations
|
81
|
+
violation_kinds = {}
|
82
|
+
@prototype.violation_kinds.each do |vk|
|
83
|
+
violation_kinds[vk.orig_key] = vk
|
84
|
+
end
|
85
|
+
|
86
|
+
result = []
|
87
|
+
|
88
|
+
@prototype.inspections.each do |proto_inspection|
|
89
|
+
proto_inspection.violations.each do |kind_id|
|
90
|
+
begin
|
91
|
+
result << Eaternet::Lives_1_0::Violation.new do |v|
|
92
|
+
v.business_id = proto_inspection.business_orig_key
|
93
|
+
v.date = Date.parse(proto_inspection.date)
|
94
|
+
v.code = violation_kinds[kind_id].code
|
95
|
+
v.description = violation_kinds[kind_id].description
|
96
|
+
end
|
97
|
+
rescue NoMethodError => e
|
98
|
+
logger.debug "Error creating violation kind #{kind_id} for inspection #{proto_inspection.orig_key}: #{e}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
result
|
124
103
|
end
|
125
104
|
end
|
126
105
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'eaternet/agencies/snhd_config'
|
3
|
+
require 'eaternet/prototype'
|
4
|
+
require 'eaternet/util'
|
5
|
+
|
6
|
+
module Eaternet
|
7
|
+
module Agencies
|
8
|
+
# An adapter for the Southern Nevada Health District (Las Vegas).
|
9
|
+
#
|
10
|
+
# @note This is a work in progress.
|
11
|
+
# @private
|
12
|
+
# @see http://southernnevadahealthdistrict.org/restaurants/inspect-downloads.php
|
13
|
+
# The SNHD Developer information page
|
14
|
+
# @see Eaternet::Prototype Framework module
|
15
|
+
class SnhdPrototype
|
16
|
+
include Eaternet::Prototype::AbstractAdapter
|
17
|
+
|
18
|
+
# (see Eaternet::Prototype::AbstractAdapter#businesses)
|
19
|
+
def businesses
|
20
|
+
lazy_csv_map('restaurant_establishments.csv') do |row|
|
21
|
+
Eaternet::Prototype::BusinessData.new(
|
22
|
+
orig_key: row['permit_number'],
|
23
|
+
name: row['restaurant_name'],
|
24
|
+
address: row['address'],
|
25
|
+
city: row['city_name'],
|
26
|
+
zipcode: row['zip_code']
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# (see Eaternet::Prototype::AbstractAdapter#inspections)
|
32
|
+
def inspections
|
33
|
+
lazy_csv_map('restaurant_inspections.csv') do |row|
|
34
|
+
if row['violations']
|
35
|
+
violations = row['violations'].split(',')
|
36
|
+
else
|
37
|
+
violations = []
|
38
|
+
end
|
39
|
+
Eaternet::Prototype::InspectionData.new(
|
40
|
+
orig_key: row['serial_number'],
|
41
|
+
business_orig_key: row['permit_number'],
|
42
|
+
score: row['inspection_grade'],
|
43
|
+
demerits: row['inspection_demerits'],
|
44
|
+
date: row['inspection_date'],
|
45
|
+
violations: violations
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# (see Eaternet::Prototype::AbstractAdapter#violations)
|
51
|
+
def violations
|
52
|
+
lazy_csv_map('restaurant_inspection_violations.csv') do |row|
|
53
|
+
Eaternet::Prototype::ViolationData.new(
|
54
|
+
orig_key: row['inspection_violation_id'],
|
55
|
+
inspection_id: row['inspection_id'],
|
56
|
+
violation_kind_id: row['inspection_violation']
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Enumerable<ViolationKindData>]
|
62
|
+
# @todo Add to AbstractAdapter
|
63
|
+
def violation_kinds
|
64
|
+
lazy_csv_map('restaurant_violations.csv') do |row|
|
65
|
+
Eaternet::Prototype::ViolationKindData.new(
|
66
|
+
orig_key: row['violation_id'],
|
67
|
+
code: row['violation_code'],
|
68
|
+
demerits: row['violation_demerits'],
|
69
|
+
description: row['violation_description']
|
70
|
+
)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def lazy_csv_map(filename, &block)
|
77
|
+
csv_rows(filename).lazy.map { |row| block.call(row) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def csv_rows(filename)
|
81
|
+
csv_reader(
|
82
|
+
path: File.join(zip_dir, filename),
|
83
|
+
headers: SnhdConfig::CSV_SCHEMA[filename]
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def csv_reader(path:, headers:)
|
88
|
+
file = open(path, encoding: 'utf-8')
|
89
|
+
file.readline # Skip the non-standard header line
|
90
|
+
CSV.new(
|
91
|
+
file,
|
92
|
+
headers: headers,
|
93
|
+
col_sep: SnhdConfig::COLUMN_SEPARATOR,
|
94
|
+
quote_char: SnhdConfig::QUOTE_CHARACTER
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def zip_dir
|
99
|
+
@zip_dir ||= Util.download_and_extract_zipfile(SnhdConfig::DOWNLOAD_URL)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/eaternet/version.rb
CHANGED
data/lib/eaternet.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'eaternet/agencies/nyc'
|
2
2
|
require 'eaternet/agencies/snhd'
|
3
|
-
require 'eaternet/agencies/snhd_lives'
|
4
3
|
|
5
4
|
module Eaternet
|
6
5
|
# Make the actual adapters easily available
|
@@ -8,7 +7,6 @@ module Eaternet
|
|
8
7
|
#
|
9
8
|
# * `Eaternet::Nyc`
|
10
9
|
# * `Eaternet::Snhd`
|
11
|
-
# * `Eaternet::SnhdLives`
|
12
10
|
include Eaternet::Agencies
|
13
11
|
end
|
14
12
|
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'eaternet/agencies/snhd_prototype'
|
3
|
+
|
4
|
+
|
5
|
+
class SnhdPrototypeAdapterTest < Minitest::Test
|
6
|
+
@@snhd_prototype = Eaternet::Agencies::SnhdPrototype.new
|
7
|
+
|
8
|
+
#
|
9
|
+
# Namespace and access
|
10
|
+
#
|
11
|
+
|
12
|
+
def test_global_namespace_not_polluted
|
13
|
+
assert_raises(NameError) { SnhdPrototype }
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# #businesses
|
18
|
+
#
|
19
|
+
|
20
|
+
def test_businesses_returns_an_enumerator
|
21
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
22
|
+
assert_kind_of Enumerable, @@snhd_prototype.businesses
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_businesses_returns_business_data_objects
|
27
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
28
|
+
assert_kind_of Eaternet::Prototype::BusinessData, @@snhd_prototype.businesses.first
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_businesses_returns_correct_data
|
33
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
34
|
+
b = @@snhd_prototype.businesses.first
|
35
|
+
assert_equal 'PR0000002', b.orig_key
|
36
|
+
assert_equal "McDonald's #3549 D HOTEL", b.name
|
37
|
+
assert_equal '301 Fremont St', b.address
|
38
|
+
assert_equal 'Las Vegas', b.city
|
39
|
+
assert_equal '89101-5600', b.zipcode
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# #inspections
|
45
|
+
#
|
46
|
+
|
47
|
+
def test_inspections_returns_an_enumerable
|
48
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
49
|
+
assert_kind_of Enumerable, @@snhd_prototype.inspections
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_inspections_returns_inspection_data_objects
|
54
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
55
|
+
assert_kind_of(
|
56
|
+
Eaternet::Prototype::InspectionData,
|
57
|
+
@@snhd_prototype.inspections.first
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_inspections_returns_correct_data
|
63
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
64
|
+
i = @@snhd_prototype.inspections.first(6).last
|
65
|
+
assert_equal 'DA0001095', i.orig_key
|
66
|
+
assert_equal 'PR0000411', i.business_orig_key
|
67
|
+
assert_equal 'A', i.score
|
68
|
+
assert_equal '1994-04-15 00:00:00', i.date
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# #violations
|
74
|
+
#
|
75
|
+
|
76
|
+
def test_violations_returns_an_enumerable
|
77
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
78
|
+
assert_kind_of Enumerable, @@snhd_prototype.violations
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_violations_returns_violation_data_objects
|
83
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
84
|
+
assert_kind_of Eaternet::Prototype::ViolationData, @@snhd_prototype.violations.first
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_violations_returns_correct_data
|
89
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
90
|
+
v = @@snhd_prototype.violations.first
|
91
|
+
assert_equal '1488', v.orig_key
|
92
|
+
assert_equal '537', v.inspection_id
|
93
|
+
assert_equal '64', v.violation_kind_id
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# #violation_kinds
|
99
|
+
#
|
100
|
+
|
101
|
+
def test_violation_kinds_returns_an_enumerable
|
102
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
103
|
+
assert_kind_of Enumerable, @@snhd_prototype.violation_kinds
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_violation_kinds_returns_violation_kind_data_objects
|
108
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
109
|
+
assert_kind_of(
|
110
|
+
Eaternet::Prototype::ViolationKindData,
|
111
|
+
@@snhd_prototype.violation_kinds.first
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_violation_kinds_returns_correct_data
|
117
|
+
VCR.use_cassette(SNHD_CASSETTE) do
|
118
|
+
v = @@snhd_prototype.violation_kinds.first
|
119
|
+
assert_equal '1', v.orig_key
|
120
|
+
assert_equal '1', v.code
|
121
|
+
assert_equal '6', v.demerits
|
122
|
+
assert_equal(
|
123
|
+
'Food not obtained from approved sources and/or improperly identified.',
|
124
|
+
v.description
|
125
|
+
)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -1,130 +1,77 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'eaternet'
|
3
3
|
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
class SnhdAdapterTest < Minitest::Test
|
4
|
+
# @todo Create proper integration vs. unit tests.
|
5
|
+
class SnhdTest < Minitest::Test
|
6
|
+
# Instantiating as an app developer would:
|
8
7
|
@@snhd = Eaternet::Snhd.new
|
9
8
|
|
10
9
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
def test_global_namespace_not_polluted
|
15
|
-
assert_raises(NameError) { Snhd }
|
16
|
-
end
|
17
|
-
|
18
|
-
#
|
19
|
-
# #businesses
|
10
|
+
# Businesses
|
20
11
|
#
|
21
12
|
|
22
|
-
def
|
13
|
+
def test_businesses_returns_an_enumerator_of_business
|
23
14
|
VCR.use_cassette(SNHD_CASSETTE) do
|
24
|
-
|
15
|
+
assert enumerable_of? Eaternet::Lives_1_0::Business, @@snhd.businesses
|
25
16
|
end
|
26
17
|
end
|
27
18
|
|
28
|
-
def
|
29
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
30
|
-
assert_kind_of Eaternet::Prototype::BusinessData, @@snhd.businesses.first
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_businesses_returns_correct_data
|
19
|
+
def test_businesses_returns_lives_attributes
|
35
20
|
VCR.use_cassette(SNHD_CASSETTE) do
|
36
21
|
b = @@snhd.businesses.first
|
37
|
-
assert_equal 'PR0000002', b.
|
22
|
+
assert_equal 'PR0000002', b.business_id
|
38
23
|
assert_equal "McDonald's #3549 D HOTEL", b.name
|
39
24
|
assert_equal '301 Fremont St', b.address
|
40
25
|
assert_equal 'Las Vegas', b.city
|
41
|
-
assert_equal '89101-5600', b.
|
26
|
+
assert_equal '89101-5600', b.postal_code
|
27
|
+
assert_equal 'NV', b.state
|
42
28
|
end
|
43
29
|
end
|
44
30
|
|
45
31
|
#
|
46
|
-
#
|
32
|
+
# Inspections
|
47
33
|
#
|
48
34
|
|
49
|
-
def
|
50
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
51
|
-
assert_kind_of Enumerable, @@snhd.inspections
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_inspections_returns_inspection_data_objects
|
35
|
+
def test_inspections_returns_an_enumerable_of_inspection
|
56
36
|
VCR.use_cassette(SNHD_CASSETTE) do
|
57
|
-
|
58
|
-
Eaternet::Prototype::InspectionData,
|
59
|
-
@@snhd.inspections.first
|
60
|
-
)
|
37
|
+
assert enumerable_of? Eaternet::Lives_1_0::Inspection, @@snhd.inspections
|
61
38
|
end
|
62
39
|
end
|
63
40
|
|
64
|
-
def
|
41
|
+
def test_inspections_returns_lives_attributes
|
65
42
|
VCR.use_cassette(SNHD_CASSETTE) do
|
66
43
|
i = @@snhd.inspections.first(6).last
|
67
|
-
assert_equal '
|
68
|
-
assert_equal
|
69
|
-
assert_equal
|
70
|
-
assert_equal '1994-04-15 00:00:00', i.date
|
44
|
+
assert_equal 'PR0000411', i.business_id
|
45
|
+
assert_equal Date.new(1994, 04, 15), i.date
|
46
|
+
assert_equal 96, i.score
|
71
47
|
end
|
72
48
|
end
|
73
49
|
|
74
50
|
#
|
75
|
-
#
|
51
|
+
# Violations
|
76
52
|
#
|
77
53
|
|
78
|
-
def
|
54
|
+
def test_violations_returns_an_enumerable_of_violation
|
79
55
|
VCR.use_cassette(SNHD_CASSETTE) do
|
80
|
-
|
56
|
+
assert enumerable_of? Eaternet::Lives_1_0::Violation, @@snhd.violations
|
81
57
|
end
|
82
58
|
end
|
83
59
|
|
84
|
-
def
|
85
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
86
|
-
assert_kind_of Eaternet::Prototype::ViolationData, @@snhd.violations.first
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_violations_returns_correct_data
|
60
|
+
def test_violations_returns_lives_attributes
|
91
61
|
VCR.use_cassette(SNHD_CASSETTE) do
|
92
62
|
v = @@snhd.violations.first
|
93
|
-
assert_equal '
|
94
|
-
assert_equal
|
95
|
-
assert_equal '
|
63
|
+
assert_equal 'PR0000411', v.business_id
|
64
|
+
assert_equal Date.new(1994, 4, 13), v.date
|
65
|
+
assert_equal '8', v.code
|
66
|
+
assert_match /hazardous salads/, v.description
|
96
67
|
end
|
97
68
|
end
|
98
69
|
|
99
70
|
#
|
100
|
-
#
|
71
|
+
# metadata
|
101
72
|
#
|
102
73
|
|
103
|
-
def
|
104
|
-
|
105
|
-
assert_kind_of Enumerable, @@snhd.violation_kinds
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def test_violation_kinds_returns_violation_kind_data_objects
|
110
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
111
|
-
assert_kind_of(
|
112
|
-
Eaternet::Prototype::ViolationKindData,
|
113
|
-
@@snhd.violation_kinds.first
|
114
|
-
)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_violation_kinds_returns_correct_data
|
119
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
120
|
-
v = @@snhd.violation_kinds.first
|
121
|
-
assert_equal '1', v.orig_key
|
122
|
-
assert_equal '1', v.code
|
123
|
-
assert_equal '6', v.demerits
|
124
|
-
assert_equal(
|
125
|
-
'Food not obtained from approved sources and/or improperly identified.',
|
126
|
-
v.description
|
127
|
-
)
|
128
|
-
end
|
74
|
+
def test_implements_feed_info
|
75
|
+
assert_instance_of Eaternet::Lives_1_0::FeedInfo, @@snhd.feed_info
|
129
76
|
end
|
130
77
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eaternet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
@@ -140,16 +140,16 @@ dependencies:
|
|
140
140
|
name: activemodel
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 3.2.21
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 3.2.21
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: rubyzip
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,7 +200,7 @@ files:
|
|
200
200
|
- lib/eaternet/agencies/nyc.rb
|
201
201
|
- lib/eaternet/agencies/snhd.rb
|
202
202
|
- lib/eaternet/agencies/snhd_config.rb
|
203
|
-
- lib/eaternet/agencies/
|
203
|
+
- lib/eaternet/agencies/snhd_prototype.rb
|
204
204
|
- lib/eaternet/lives_1_0.rb
|
205
205
|
- lib/eaternet/lives_1_0/adapter.rb
|
206
206
|
- lib/eaternet/lives_1_0/business.rb
|
@@ -216,7 +216,7 @@ files:
|
|
216
216
|
- lib/eaternet/version.rb
|
217
217
|
- lib/ext/enumerator.rb
|
218
218
|
- test/eaternet/agencies/nyc_test.rb
|
219
|
-
- test/eaternet/agencies/
|
219
|
+
- test/eaternet/agencies/snhd_prototype_test.rb
|
220
220
|
- test/eaternet/agencies/snhd_test.rb
|
221
221
|
- test/eaternet/eaternet_test.rb
|
222
222
|
- test/eaternet/lives_1_0/business_test.rb
|
@@ -255,7 +255,7 @@ specification_version: 4
|
|
255
255
|
summary: Regional adapters for restaurant health scores
|
256
256
|
test_files:
|
257
257
|
- test/eaternet/agencies/nyc_test.rb
|
258
|
-
- test/eaternet/agencies/
|
258
|
+
- test/eaternet/agencies/snhd_prototype_test.rb
|
259
259
|
- test/eaternet/agencies/snhd_test.rb
|
260
260
|
- test/eaternet/eaternet_test.rb
|
261
261
|
- test/eaternet/lives_1_0/business_test.rb
|
@@ -268,4 +268,3 @@ test_files:
|
|
268
268
|
- test/fixtures/morris-park-bake-shop.csv
|
269
269
|
- test/script.rb
|
270
270
|
- test/test_helper.rb
|
271
|
-
has_rdoc:
|
@@ -1,106 +0,0 @@
|
|
1
|
-
require 'date'
|
2
|
-
require 'eaternet/loggable'
|
3
|
-
require 'eaternet/util'
|
4
|
-
|
5
|
-
module Eaternet
|
6
|
-
module Agencies
|
7
|
-
class SnhdLives < Eaternet::Lives_1_0::Adapter
|
8
|
-
include Eaternet::Lives_1_0
|
9
|
-
include Eaternet::Loggable
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@prototype = Eaternet::Agencies::Snhd.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def businesses
|
16
|
-
@prototype.businesses
|
17
|
-
.map { |proto| try_to_create_business(proto) }
|
18
|
-
end
|
19
|
-
|
20
|
-
def inspections
|
21
|
-
@prototype.inspections
|
22
|
-
.map { |proto| try_to_create_inspection(proto) }
|
23
|
-
end
|
24
|
-
|
25
|
-
def try_to_create_business(proto)
|
26
|
-
business(proto)
|
27
|
-
rescue ArgumentError => e
|
28
|
-
logger.warn('SNHD LIVES adapter') do
|
29
|
-
"Could not create a LIVES Business from #{proto.inspect}: #{e}"
|
30
|
-
end
|
31
|
-
nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def try_to_create_inspection(proto)
|
35
|
-
inspection(proto)
|
36
|
-
rescue ArgumentError => e
|
37
|
-
logger.warn('SNHD LIVES adapter') do
|
38
|
-
"Could not create a LIVES Inspection from #{proto.inspect}: #{e}"
|
39
|
-
end
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
|
43
|
-
def business(proto)
|
44
|
-
Business.new do |b|
|
45
|
-
b.business_id = proto.orig_key
|
46
|
-
b.name = proto.name
|
47
|
-
b.address = proto.address
|
48
|
-
b.city = proto.city
|
49
|
-
b.postal_code = proto.zipcode
|
50
|
-
b.state = 'NV'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def inspection(proto)
|
55
|
-
Inspection.new do |i|
|
56
|
-
i.business_id = proto.business_orig_key
|
57
|
-
i.score = proto.demerits.nil? ? nil : 100 - proto.demerits.to_i
|
58
|
-
i.date = Date.parse(proto.date)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def violations
|
63
|
-
@violations ||= _violations
|
64
|
-
end
|
65
|
-
|
66
|
-
def feed_info
|
67
|
-
FeedInfo.new do |fi|
|
68
|
-
fi.feed_date = Date.today
|
69
|
-
fi.feed_version = '1.0'
|
70
|
-
fi.municipality_name = 'Southern Nevada'
|
71
|
-
fi.municipality_url = 'http://southernnevadahealthdistrict.org/restaurants/index.php'
|
72
|
-
fi.contact_email = 'environmentalhealth@snhdmail.org'
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def legends
|
77
|
-
[]
|
78
|
-
end
|
79
|
-
|
80
|
-
def _violations
|
81
|
-
violation_kinds = {}
|
82
|
-
@prototype.violation_kinds.each do |vk|
|
83
|
-
violation_kinds[vk.orig_key] = vk
|
84
|
-
end
|
85
|
-
|
86
|
-
result = []
|
87
|
-
|
88
|
-
@prototype.inspections.each do |proto_inspection|
|
89
|
-
proto_inspection.violations.each do |kind_id|
|
90
|
-
begin
|
91
|
-
result << Violation.new do |v|
|
92
|
-
v.business_id = proto_inspection.business_orig_key
|
93
|
-
v.date = Date.parse(proto_inspection.date)
|
94
|
-
v.code = violation_kinds[kind_id].code
|
95
|
-
v.description = violation_kinds[kind_id].description
|
96
|
-
end
|
97
|
-
rescue NoMethodError => e
|
98
|
-
logger.debug "Error creating violation kind #{kind_id} for inspection #{proto_inspection.orig_key}: #{e}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
result
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'eaternet'
|
3
|
-
|
4
|
-
class SnhdLivesTest < Minitest::Test
|
5
|
-
@@snhd = Eaternet::SnhdLives.new
|
6
|
-
|
7
|
-
#
|
8
|
-
# Businesses
|
9
|
-
#
|
10
|
-
|
11
|
-
def test_businesses_returns_an_enumerator_of_business
|
12
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
13
|
-
assert enumerable_of? Eaternet::Lives_1_0::Business, @@snhd.businesses
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_businesses_returns_lives_attributes
|
18
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
19
|
-
b = @@snhd.businesses.first
|
20
|
-
assert_equal 'PR0000002', b.business_id
|
21
|
-
assert_equal "McDonald's #3549 D HOTEL", b.name
|
22
|
-
assert_equal '301 Fremont St', b.address
|
23
|
-
assert_equal 'Las Vegas', b.city
|
24
|
-
assert_equal '89101-5600', b.postal_code
|
25
|
-
assert_equal 'NV', b.state
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
#
|
30
|
-
# Inspections
|
31
|
-
#
|
32
|
-
|
33
|
-
def test_inspections_returns_an_enumerable_of_inspection
|
34
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
35
|
-
assert enumerable_of? Eaternet::Lives_1_0::Inspection, @@snhd.inspections
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_inspections_returns_lives_attributes
|
40
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
41
|
-
i = @@snhd.inspections.first(6).last
|
42
|
-
assert_equal 'PR0000411', i.business_id
|
43
|
-
assert_equal Date.new(1994, 04, 15), i.date
|
44
|
-
assert_equal 96, i.score
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# Violations
|
50
|
-
#
|
51
|
-
|
52
|
-
def test_violations_returns_an_enumerable_of_violation
|
53
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
54
|
-
assert enumerable_of? Eaternet::Lives_1_0::Violation, @@snhd.violations
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_violations_returns_lives_attributes
|
59
|
-
VCR.use_cassette(SNHD_CASSETTE) do
|
60
|
-
v = @@snhd.violations.first
|
61
|
-
assert_equal 'PR0000411', v.business_id
|
62
|
-
assert_equal Date.new(1994, 4, 13), v.date
|
63
|
-
assert_equal '8', v.code
|
64
|
-
assert_match /hazardous salads/, v.description
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
#
|
69
|
-
# metadata
|
70
|
-
#
|
71
|
-
|
72
|
-
def test_implements_feed_info
|
73
|
-
assert_instance_of Eaternet::Lives_1_0::FeedInfo, @@snhd.feed_info
|
74
|
-
end
|
75
|
-
end
|