eaternet 1.0.1 → 1.0.2
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 +4 -4
- data/.gitignore +1 -0
- data/lib/eaternet.rb +3 -1
- data/lib/eaternet/agencies/sf.rb +86 -0
- data/lib/eaternet/lives_1_0/csv_parser.rb +40 -0
- data/lib/eaternet/version.rb +1 -1
- data/test/eaternet/agencies/sf_test.rb +87 -0
- data/test/test_helper.rb +2 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 928eb7167530d756d5a7b031388d09a511bb0bb4
|
4
|
+
data.tar.gz: 9f692333174312985c4cffc6904402afe7f7d199
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f08b598e00b84458f74914bd436d5104c2b3c964312dbd728a340aa68fcea6f60ea13659180640cb58f662cf3ac53c0211a54f93ef16f3a94d8b5230a12bb699
|
7
|
+
data.tar.gz: 5cf0c325b95f29bc3bd205ebb137c9f9ad5bcf38fac647327680b03bbba0a153f7f82533f8aca5e79d44e989ba5ef68066837cd4a087a081a96ab2fdaac865b9
|
data/.gitignore
CHANGED
data/lib/eaternet.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
require 'eaternet/agencies/multco'
|
2
2
|
require 'eaternet/agencies/nyc'
|
3
|
+
require 'eaternet/agencies/sf'
|
3
4
|
require 'eaternet/agencies/snhd'
|
4
5
|
|
5
6
|
module Eaternet
|
6
7
|
# Make the actual adapters easily available
|
7
8
|
# to the application-level as:
|
8
9
|
#
|
9
|
-
# * `Eaternet::Multco` — Portland area, Oregon, USA
|
10
10
|
# * `Eaternet::Nyc` – New York City
|
11
|
+
# * `Eaternet::Sf` - San Francisco
|
11
12
|
# * `Eaternet::Snhd` — Las Vegas area
|
13
|
+
# * `Eaternet::Multco` — Portland area, Oregon, USA
|
12
14
|
include Eaternet::Agencies
|
13
15
|
end
|
14
16
|
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
require 'eaternet/lives_1_0/adapter'
|
5
|
+
require 'eaternet/lives_1_0/csv_parser'
|
6
|
+
require 'eaternet/loggable'
|
7
|
+
require 'eaternet/util'
|
8
|
+
|
9
|
+
module Eaternet
|
10
|
+
module Agencies
|
11
|
+
class Sf < Eaternet::Lives_1_0::Adapter
|
12
|
+
include Eaternet::Loggable
|
13
|
+
include Eaternet::Lives_1_0::CsvParser
|
14
|
+
|
15
|
+
def businesses
|
16
|
+
convert csv: 'businesses.csv', to_type: :business
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspections
|
20
|
+
convert csv: 'inspections.csv', to_type: :inspection
|
21
|
+
end
|
22
|
+
|
23
|
+
def violations
|
24
|
+
convert csv: 'violations.csv', to_type: :violation
|
25
|
+
end
|
26
|
+
|
27
|
+
def feed_info
|
28
|
+
Eaternet::Lives_1_0::FeedInfo.new do |fi|
|
29
|
+
fi.feed_date = Date.today
|
30
|
+
fi.feed_version = '1.0'
|
31
|
+
fi.municipality_name = 'San Francisco'
|
32
|
+
fi.municipality_url = 'https://www.sfdph.org/dph/EH/Food/Score/default.asp'
|
33
|
+
fi.contact_email = 'contact@sfdph.org'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def adapter_name
|
38
|
+
'SF'
|
39
|
+
end
|
40
|
+
|
41
|
+
def zip_file_url
|
42
|
+
'https://extxfer.sfdph.org/food/SFBusinesses.zip'
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def business(csv_row)
|
48
|
+
Eaternet::Lives_1_0::Business.new do |b|
|
49
|
+
csv_row.headers.each do |header|
|
50
|
+
b.send("#{header.downcase}=", csv_row[header])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def inspection(csv_row)
|
56
|
+
Eaternet::Lives_1_0::Inspection.new do |b|
|
57
|
+
csv_row.headers.each do |header|
|
58
|
+
b.send("#{header.downcase}=", csv_row[header])
|
59
|
+
b.date = Date.parse(csv_row['date'])
|
60
|
+
b.score = csv_row['Score'].to_i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def violation(csv_row)
|
66
|
+
Eaternet::Lives_1_0::Violation.new do |b|
|
67
|
+
csv_row.headers.each do |header|
|
68
|
+
b.send("#{header.downcase}=", csv_row[header])
|
69
|
+
b.date = Date.parse(csv_row['date'])
|
70
|
+
b.description = fix(description: csv_row['description'])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def fix(description:)
|
76
|
+
# Remove bracketed violation facts, non-conforming to LIVES
|
77
|
+
return description unless description =~ /^([^\[]+)/
|
78
|
+
$1.strip
|
79
|
+
end
|
80
|
+
|
81
|
+
def csv_reader(path:)
|
82
|
+
CSV.new(open(path, encoding: 'ISO-8859-1'), headers: true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Eaternet
|
2
|
+
module Lives_1_0
|
3
|
+
module CsvParser
|
4
|
+
|
5
|
+
def adapter_name
|
6
|
+
fail 'Override with a name for log output, e.g. "SF"'
|
7
|
+
end
|
8
|
+
|
9
|
+
def zip_file_url
|
10
|
+
fail 'Override with the zip archive location'
|
11
|
+
end
|
12
|
+
|
13
|
+
def convert(csv:, to_type:)
|
14
|
+
csv_map(csv) { |row| try_to_create to_type, from_csv_row: row }
|
15
|
+
end
|
16
|
+
|
17
|
+
def csv_map(filename, &block)
|
18
|
+
csv_rows(filename).lazy.map { |row| block.call(row) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def csv_rows(filename)
|
22
|
+
csv_reader(path: File.join(zip_dir, filename))
|
23
|
+
end
|
24
|
+
|
25
|
+
def zip_dir
|
26
|
+
@zip_dir ||= Util.download_and_extract_zipfile(zip_file_url)
|
27
|
+
end
|
28
|
+
|
29
|
+
def try_to_create(entity_type, from_csv_row:)
|
30
|
+
send(entity_type, from_csv_row)
|
31
|
+
rescue ArgumentError => e
|
32
|
+
logger.warn("#{adapter_name} LIVES adapter") do
|
33
|
+
"Couldn't create a LIVES #{entity_type} from #{from_csv_row.inspect}: #{e}"
|
34
|
+
end
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/eaternet/version.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'eaternet'
|
3
|
+
|
4
|
+
class SfTest < Minitest::Test
|
5
|
+
# Instantiating as an app developer would:
|
6
|
+
@@sf = Eaternet::Sf.new
|
7
|
+
|
8
|
+
#
|
9
|
+
# Businesses
|
10
|
+
#
|
11
|
+
|
12
|
+
def test_businesses_returns_an_enumerator_of_business
|
13
|
+
VCR.use_cassette(SF_CASSETTE) do
|
14
|
+
assert enumerable_of? Eaternet::Lives_1_0::Business, @@sf.businesses
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_businesses_returns_lives_attributes
|
19
|
+
VCR.use_cassette(SF_CASSETTE) do
|
20
|
+
b = @@sf.businesses.first
|
21
|
+
assert_equal '10', b.business_id
|
22
|
+
assert_equal 'TIRAMISU KITCHEN', b.name
|
23
|
+
assert_equal '033 BELDEN PL', b.address
|
24
|
+
assert_equal 'San Francisco', b.city
|
25
|
+
assert_equal '94104', b.postal_code
|
26
|
+
assert_equal 'CA', b.state
|
27
|
+
assert_equal '37.791116', b.latitude
|
28
|
+
assert_equal '-122.403816', b.longitude
|
29
|
+
assert_equal '', b.phone_number
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Inspections
|
35
|
+
#
|
36
|
+
|
37
|
+
def test_inspections_returns_an_enumerable_of_inspection
|
38
|
+
VCR.use_cassette(SF_CASSETTE) do
|
39
|
+
assert enumerable_of? Eaternet::Lives_1_0::Inspection, @@sf.inspections
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_inspections_returns_lives_attributes
|
44
|
+
VCR.use_cassette(SF_CASSETTE) do
|
45
|
+
i = @@sf.inspections.first(6).last
|
46
|
+
assert_equal '17', i.business_id
|
47
|
+
assert_equal Date.new(2012, 8, 23), i.date
|
48
|
+
assert_equal 100, i.score
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Violations
|
54
|
+
#
|
55
|
+
|
56
|
+
def test_violations_returns_an_enumerable_of_violation
|
57
|
+
VCR.use_cassette(SF_CASSETTE) do
|
58
|
+
assert enumerable_of? Eaternet::Lives_1_0::Violation, @@sf.violations
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_violations_returns_lives_attributes
|
63
|
+
VCR.use_cassette(SF_CASSETTE) do
|
64
|
+
v = @@sf.violations.first
|
65
|
+
assert_equal '10', v.business_id
|
66
|
+
assert_equal Date.new(2014, 7, 29), v.date
|
67
|
+
assert_equal nil, v.code
|
68
|
+
assert_match /^Insufficient hot water or running water$/, v.description
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# metadata
|
74
|
+
#
|
75
|
+
|
76
|
+
def test_implements_feed_info
|
77
|
+
assert_instance_of Eaternet::Lives_1_0::FeedInfo, @@sf.feed_info
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Other
|
82
|
+
#
|
83
|
+
|
84
|
+
def test_handles_file_encoding
|
85
|
+
refute_nil @@sf.businesses.to_a
|
86
|
+
end
|
87
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -8,7 +8,7 @@ VCR.configure do |c|
|
|
8
8
|
c.cassette_library_dir = 'test/vcr_cassettes'
|
9
9
|
c.hook_into :webmock
|
10
10
|
c.ignore_hosts 'downloadtest.com'
|
11
|
-
c.default_cassette_options = { record: :new_episodes }
|
11
|
+
# c.default_cassette_options = { record: :new_episodes }
|
12
12
|
end
|
13
13
|
|
14
14
|
#
|
@@ -20,3 +20,4 @@ def enumerable_of?(a_class, obj)
|
|
20
20
|
end
|
21
21
|
|
22
22
|
SNHD_CASSETTE = 'snhd'
|
23
|
+
SF_CASSETTE = 'sf'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eaternet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -242,12 +242,14 @@ files:
|
|
242
242
|
- lib/eaternet/agencies/multco.rb
|
243
243
|
- lib/eaternet/agencies/multco_lib/misc.rb
|
244
244
|
- lib/eaternet/agencies/nyc.rb
|
245
|
+
- lib/eaternet/agencies/sf.rb
|
245
246
|
- lib/eaternet/agencies/snhd.rb
|
246
247
|
- lib/eaternet/agencies/snhd_config.rb
|
247
248
|
- lib/eaternet/agencies/snhd_prototype.rb
|
248
249
|
- lib/eaternet/lives_1_0.rb
|
249
250
|
- lib/eaternet/lives_1_0/adapter.rb
|
250
251
|
- lib/eaternet/lives_1_0/business.rb
|
252
|
+
- lib/eaternet/lives_1_0/csv_parser.rb
|
251
253
|
- lib/eaternet/lives_1_0/feed_info.rb
|
252
254
|
- lib/eaternet/lives_1_0/inspection.rb
|
253
255
|
- lib/eaternet/lives_1_0/legend.rb
|
@@ -261,6 +263,7 @@ files:
|
|
261
263
|
- lib/ext/enumerator.rb
|
262
264
|
- test/eaternet/agencies/multco_test.rb
|
263
265
|
- test/eaternet/agencies/nyc_test.rb
|
266
|
+
- test/eaternet/agencies/sf_test.rb
|
264
267
|
- test/eaternet/agencies/snhd_prototype_test.rb
|
265
268
|
- test/eaternet/agencies/snhd_test.rb
|
266
269
|
- test/eaternet/eaternet_test.rb
|
@@ -294,13 +297,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
294
297
|
version: '0'
|
295
298
|
requirements: []
|
296
299
|
rubyforge_project:
|
297
|
-
rubygems_version: 2.4.
|
300
|
+
rubygems_version: 2.4.8
|
298
301
|
signing_key:
|
299
302
|
specification_version: 4
|
300
303
|
summary: Regional adapters for restaurant health scores
|
301
304
|
test_files:
|
302
305
|
- test/eaternet/agencies/multco_test.rb
|
303
306
|
- test/eaternet/agencies/nyc_test.rb
|
307
|
+
- test/eaternet/agencies/sf_test.rb
|
304
308
|
- test/eaternet/agencies/snhd_prototype_test.rb
|
305
309
|
- test/eaternet/agencies/snhd_test.rb
|
306
310
|
- test/eaternet/eaternet_test.rb
|
@@ -314,3 +318,4 @@ test_files:
|
|
314
318
|
- test/fixtures/morris-park-bake-shop.csv
|
315
319
|
- test/script.rb
|
316
320
|
- test/test_helper.rb
|
321
|
+
has_rdoc:
|