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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a0ddbd370e7b0031ec01be4326651038c0c39e0
4
- data.tar.gz: a79d320f380f19320389aba560df3e5d7b82360c
3
+ metadata.gz: 928eb7167530d756d5a7b031388d09a511bb0bb4
4
+ data.tar.gz: 9f692333174312985c4cffc6904402afe7f7d199
5
5
  SHA512:
6
- metadata.gz: 883b37c06d500ffc1465f37dba5a4682dd848cd32450db73d0e4ddbff4dd8b50043f79ae0501fb97926be527e69451300f81c8090a2f9db024219eb34c9ef24e
7
- data.tar.gz: 4908a880ffd3a97430789da41652ab611246b30ea2635013872ad657c80cbb6d3ea1796f93cc78f9e939dacb34f874b696c4e45fc227137d73308787337f0704
6
+ metadata.gz: f08b598e00b84458f74914bd436d5104c2b3c964312dbd728a340aa68fcea6f60ea13659180640cb58f662cf3ac53c0211a54f93ef16f3a94d8b5230a12bb699
7
+ data.tar.gz: 5cf0c325b95f29bc3bd205ebb137c9f9ad5bcf38fac647327680b03bbba0a153f7f82533f8aca5e79d44e989ba5ef68066837cd4a087a081a96ab2fdaac865b9
data/.gitignore CHANGED
@@ -18,6 +18,7 @@ mkmf.log
18
18
  /vcr_cassettes/
19
19
  /test/vcr_cassettes/
20
20
  .minitest-perf.db
21
+ log.txt
21
22
 
22
23
  # IDE's
23
24
  *.komodoproject
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
@@ -1,3 +1,3 @@
1
1
  module Eaternet
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -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.1
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-05 00:00:00.000000000 Z
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.7
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: