eaternet 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|