eaternet 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4593dfcf3a89703992a04487b287240043dfd3d4
4
- data.tar.gz: 1b766e1829a7b3bb3c79ea2a67b628bd6a0a9c78
3
+ metadata.gz: 9a0ddbd370e7b0031ec01be4326651038c0c39e0
4
+ data.tar.gz: a79d320f380f19320389aba560df3e5d7b82360c
5
5
  SHA512:
6
- metadata.gz: 1b3f69b0b5b9ee069e413f9fa773e41be46fb2ec69d48e62b945d9a74441050e636cced72de54797fe79a4d9d39dce9fd5597f08c0d79e03ec05a75645181816
7
- data.tar.gz: 80e086a93cb536589a9756025b1712dee785a2914649707ad4f107566c74702fab75c4aff53c1801770ec6a3bb4450c8bd4435a565459bdbdde3059ee24f744f
6
+ metadata.gz: 883b37c06d500ffc1465f37dba5a4682dd848cd32450db73d0e4ddbff4dd8b50043f79ae0501fb97926be527e69451300f81c8090a2f9db024219eb34c9ef24e
7
+ data.tar.gz: 4908a880ffd3a97430789da41652ab611246b30ea2635013872ad657c80cbb6d3ea1796f93cc78f9e939dacb34f874b696c4e45fc227137d73308787337f0704
data/.gitignore CHANGED
@@ -17,6 +17,7 @@ mkmf.log
17
17
  /tmp/
18
18
  /vcr_cassettes/
19
19
  /test/vcr_cassettes/
20
+ .minitest-perf.db
20
21
 
21
22
  # IDE's
22
23
  *.komodoproject
data/eaternet.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'guard'
24
24
  spec.add_development_dependency 'guard-minitest'
25
25
  spec.add_development_dependency 'minitest'
26
+ spec.add_development_dependency 'minitest-perf'
26
27
  spec.add_development_dependency 'pry'
27
28
  spec.add_development_dependency 'rake', '~> 10'
28
29
  spec.add_development_dependency 'timecop'
@@ -30,6 +31,8 @@ Gem::Specification.new do |spec|
30
31
  spec.add_development_dependency 'webmock'
31
32
 
32
33
  spec.add_runtime_dependency 'activemodel', '>= 3.2.21'
33
- spec.add_runtime_dependency 'rubyzip'
34
34
  spec.add_runtime_dependency 'httparty'
35
+ spec.add_runtime_dependency 'mechanize'
36
+ spec.add_runtime_dependency 'nokogiri'
37
+ spec.add_runtime_dependency 'rubyzip'
35
38
  end
data/lib/eaternet.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'eaternet/agencies/multco'
1
2
  require 'eaternet/agencies/nyc'
2
3
  require 'eaternet/agencies/snhd'
3
4
 
@@ -5,8 +6,9 @@ module Eaternet
5
6
  # Make the actual adapters easily available
6
7
  # to the application-level as:
7
8
  #
8
- # * `Eaternet::Nyc`
9
- # * `Eaternet::Snhd`
9
+ # * `Eaternet::Multco` — Portland area, Oregon, USA
10
+ # * `Eaternet::Nyc` – New York City
11
+ # * `Eaternet::Snhd` — Las Vegas area
10
12
  include Eaternet::Agencies
11
13
  end
12
14
 
@@ -0,0 +1,178 @@
1
+ require 'mechanize'
2
+ require 'nokogiri'
3
+
4
+ require 'eaternet/agencies/multco_lib/misc'
5
+ require 'eaternet/lives_1_0'
6
+ require 'eaternet/loggable'
7
+
8
+ module Eaternet
9
+ module Agencies
10
+ class Multco < Eaternet::Lives_1_0::Adapter
11
+ include Eaternet::Loggable
12
+
13
+ def businesses
14
+ @businesses ||= multco_get_index do |struct|
15
+ Eaternet::Lives_1_0::Business.new do |b|
16
+ b.business_id = struct['orig_key']
17
+ b.address = struct['address']
18
+ b.city = struct['city']
19
+ b.state = 'OR'
20
+ b.name = struct['name']
21
+ b.postal_code = struct['zipcode']
22
+ end
23
+ end
24
+ end
25
+
26
+ def inspections
27
+ @violations = []
28
+ import_inspections_and_capture_violations.map { |struct| try_to_create_inspection(struct) }
29
+ .compact
30
+ end
31
+
32
+ def violations
33
+ inspections if @violations.nil?
34
+ @violations.map { |struct| try_to_create_violation(struct) }
35
+ .compact
36
+ end
37
+
38
+ def feed_info
39
+ Eaternet::Lives_1_0::FeedInfo.new do |fi|
40
+ fi.feed_date = Date.today
41
+ fi.feed_version = '1.0'
42
+ fi.municipality_name = 'Multnomah County, Oregon'
43
+ fi.municipality_url = 'https://multco.us/services/restaurants'
44
+ fi.contact_email = 'foodsafety@multco.us'
45
+ end
46
+ end
47
+
48
+
49
+ private
50
+
51
+ def try_to_create_inspection(struct)
52
+ inspection(struct)
53
+ rescue ArgumentError => e
54
+ logger.warn('Multnomah County LIVES adapter') do
55
+ "Could not create a LIVES Inspection from #{struct.inspect}: #{e}"
56
+ end
57
+ nil
58
+ end
59
+
60
+ def inspection(struct)
61
+ Eaternet::Lives_1_0::Inspection.new do |i|
62
+ i.business_id = struct[:business_id]
63
+ i.score = struct[:score]
64
+ i.date = struct[:date]
65
+ end
66
+ end
67
+
68
+ def try_to_create_violation(struct)
69
+ violation(struct)
70
+ rescue ArgumentError => e
71
+ logger.warn('Multnomah County LIVES adapter') do
72
+ "Could not create a LIVES Violation from #{struct.inspect}: #{e}"
73
+ end
74
+ nil
75
+ end
76
+
77
+ def violation(struct)
78
+ Eaternet::Lives_1_0::Violation.new do |v|
79
+ v.business_id = struct[:business_id]
80
+ v.date = struct[:date]
81
+ v.code = struct[:code]
82
+ v.description = struct[:description]
83
+ end
84
+ end
85
+
86
+ def multco_get_index
87
+ result = []
88
+ agent = Mechanize.new
89
+ agent.get('http://www3.multco.us/MCHealthInspect/ListSearch.aspx')
90
+ agent.page.forms[0].click_button
91
+ form = agent.page.forms[0]
92
+ button_next = form.button_with(id: 'Next')
93
+
94
+ until button_next.nil?
95
+ agent.page.search('table#ResultsDataGrid > tr').each do |tr|
96
+ d = multco_parse_business_table_row(tr)
97
+ next if d.nil? || Eaternet::Agencies::MultcoLib::Misc.blacklisted?(name: d['name'])
98
+ result << yield(d)
99
+ end
100
+ # Go to the next page
101
+ form.click_button(button_next)
102
+ form = agent.page.forms[0]
103
+ button_next = form.button_with(id: 'Next')
104
+ end
105
+ result
106
+ end
107
+
108
+ def multco_parse_business_table_row(tr)
109
+ result = {}
110
+
111
+ columns = tr.search('td')
112
+ link = columns[0].search('a')
113
+ return nil if link.nil?
114
+
115
+ link.to_html =~ /id=([^"]+)/
116
+ orig_key = Regexp.last_match(1)
117
+ return nil unless orig_key
118
+
119
+ result['name'] = columns[0].inner_text.strip
120
+ result['address'] = columns[1].inner_text.strip
121
+ result['city'] = columns[2].inner_text.strip
122
+ result['zipcode'] = columns[3].inner_text.strip
123
+ result['orig_key'] = orig_key
124
+ result['detail_page'] = link
125
+
126
+ return nil if multco_unwanted?(result)
127
+ result
128
+ end
129
+
130
+ def multco_unwanted?(business_data)
131
+ # Throw out weird "Surveillance" results
132
+ return true if business_data['name'] =~ /(Surveill|Surlleillance)/i
133
+
134
+ # Throw out food carts
135
+ return true if business_data['address'].blank?
136
+
137
+ false
138
+ end
139
+
140
+ def import_inspections_and_capture_violations
141
+ result = []
142
+
143
+ businesses.each do |business|
144
+ Eaternet::Agencies::MultcoLib::Misc.inspection_pages(business.business_id).each do |page|
145
+ inspection_struct = import_inspection(page, business)
146
+ next if inspection_struct.nil?
147
+ result << inspection_struct
148
+ @violations += import_violations(page, inspection_struct)
149
+ end
150
+ end
151
+
152
+ result
153
+ end
154
+
155
+ def import_inspection(page, business)
156
+ i = Eaternet::Agencies::MultcoLib::Misc.parse_inspection(page: page)
157
+ return if i.nil?
158
+ {
159
+ business_id: business.business_id,
160
+ score: i['score'],
161
+ date: i['date']
162
+ }
163
+ end
164
+
165
+ def import_violations(page, inspection)
166
+ Eaternet::Agencies::MultcoLib::Misc.parse_violations(page: page).map do |v|
167
+ {
168
+ business_id: inspection[:business_id],
169
+ date: inspection[:date],
170
+ code: v[:code_number],
171
+ description: v[:code_description],
172
+ facts: v[:facts]
173
+ }
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,106 @@
1
+ require 'eaternet/lives_1_0'
2
+
3
+ module Eaternet
4
+ module Agencies
5
+ module MultcoLib
6
+ module Misc
7
+ def self.blacklisted?(name:)
8
+ return true if name =~ /Chartwells/ # Apparently bad data
9
+ return true if name =~ /Doubletree/ # Apparently bad data
10
+ return true if name =~ /Providence Park/ # Yelp's model mismatch
11
+ false
12
+ end
13
+
14
+ def self.parse_violations_from_html(a_string)
15
+ page = Mechanize::Page.new(nil,
16
+ { 'content-type' => 'text/html' },
17
+ a_string,
18
+ nil,
19
+ Mechanize.new)
20
+ parse_violations(page: page)
21
+ end
22
+
23
+ def self.inspection_pages(business_id)
24
+ results = []
25
+ page = latest_inspection_page(business_id)
26
+ loop do
27
+ results << page
28
+ form = page.forms.first
29
+ button = form.button_with(id: 'NextInspection')
30
+ break if button.nil?
31
+ courtesy_delay
32
+ page = form.submit(button)
33
+ end
34
+ results
35
+ end
36
+
37
+ def self.latest_inspection_page(id)
38
+ agent = Mechanize.new
39
+ courtesy_delay
40
+ url = "http://www3.multco.us/MCHealthInspect/ListSearch.aspx?id=#{id}"
41
+ agent.get(url)
42
+ agent.page
43
+ end
44
+
45
+ def self.parse_inspection(page:)
46
+ result = {}
47
+ cells = page.search('td.DetailsTD')
48
+ return nil if cells.size == 0
49
+ result['inspection_number'] = cells[0].inner_text.gsub(/[^0-9]/, '')
50
+ date_text = cells[2].inner_text.strip.gsub(/[^0-9\/]/, '')
51
+ date_text =~ %r{(\d\d)/(\d\d)/(\d\d\d\d)}
52
+ result['date'] = Date.parse "#{Regexp.last_match(3)}-#{Regexp.last_match(1)}-#{Regexp.last_match(2)}"
53
+ result['score'] = cells[3].inner_text.gsub(/[^0-9]/, '').to_i
54
+ return nil if result['score'] == 0
55
+ result
56
+ end
57
+
58
+ def self.parse_violations(page:)
59
+ next_is_a_violation = false
60
+ page.search('tr').map do |tr|
61
+ if tr.inner_text =~ /Law\/Rule/
62
+ next_is_a_violation = true
63
+ next
64
+ end
65
+ next unless next_is_a_violation
66
+ next_is_a_violation = false
67
+
68
+ parse_violation_row(tr)
69
+ end.compact
70
+ end
71
+
72
+ def self.parse_violation_row(tr)
73
+ cells = tr.search('td.DetailsTD')
74
+ result = {
75
+ code_number: clean_inner_text(cells[0]),
76
+ facts: clean_inner_text(cells[2]),
77
+ code_description: clean_inner_text(cells[1])
78
+ }
79
+ valid_result?(parsed_data: result) ? result : nil
80
+ end
81
+
82
+ def self.valid_result?(parsed_data:)
83
+ valid_code_number?(parsed_data[:code_number]) &&
84
+ !parsed_data[:facts].start_with?('INFORMATIONAL') &&
85
+ !parsed_data.values.reduce(:+).blank?
86
+ end
87
+
88
+ def self.clean_inner_text(elem)
89
+ elem.nil? ? '' : better_strip(elem.inner_text)
90
+ end
91
+
92
+ def self.valid_code_number?(n)
93
+ !(n =~ /^(99.*|98[A-Z])$/)
94
+ end
95
+
96
+ def self.better_strip(a_string)
97
+ a_string.sub(/\p{Blank}+\z/, '').sub(/^\p{Blank}+/, '').strip
98
+ end
99
+
100
+ def self.courtesy_delay
101
+ # sleep 0.25
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -45,7 +45,6 @@ module Eaternet
45
45
  #
46
46
  # @see https://data.cityofnewyork.us/Health/DOHMH-New-York-City-Restaurant-Inspection-Results/xx67-kt59 NYC health scores official data, hosted on Socrata
47
47
  class Nyc < Eaternet::Lives_1_0::Adapter
48
- include Eaternet::Lives_1_0
49
48
  include Eaternet::Loggable
50
49
 
51
50
  # Create an NYC data-source, ready for querying.
@@ -101,7 +100,7 @@ module Eaternet
101
100
  # @return [FeedInfo]
102
101
  def feed_info
103
102
  # Anyone know a contact email?
104
- FeedInfo.new do |fi|
103
+ Eaternet::Lives_1_0::FeedInfo.new do |fi|
105
104
  fi.feed_date = Date.today
106
105
  fi.feed_version = '1.0'
107
106
  fi.municipality_name = 'New York City'
@@ -111,19 +110,19 @@ module Eaternet
111
110
 
112
111
  # @return [Enumerable<Legend>]
113
112
  def legends
114
- LegendGroup.new do |lg|
113
+ Eaternet::Lives_1_0::LegendGroup.new do |lg|
115
114
  lg.legends = [
116
- Legend.new do |l|
115
+ Eaternet::Lives_1_0::Legend.new do |l|
117
116
  l.minimum_score = 87
118
117
  l.maximum_score = 100
119
118
  l.description = 'A'
120
119
  end,
121
- Legend.new do |l|
120
+ Eaternet::Lives_1_0::Legend.new do |l|
122
121
  l.minimum_score = 73
123
122
  l.maximum_score = 86
124
123
  l.description = 'B'
125
124
  end,
126
- Legend.new do |l|
125
+ Eaternet::Lives_1_0::Legend.new do |l|
127
126
  l.minimum_score = 0
128
127
  l.maximum_score = 72
129
128
  l.description = 'C'
@@ -159,7 +158,7 @@ module Eaternet
159
158
  def business(row)
160
159
  address = "#{row['BUILDING']} #{row['STREET']}"
161
160
 
162
- Business.new do |b|
161
+ Eaternet::Lives_1_0::Business.new do |b|
163
162
  b.business_id = business_id(row)
164
163
  b.name = row['DBA']
165
164
  b.address = address
@@ -173,7 +172,7 @@ module Eaternet
173
172
  private
174
173
 
175
174
  def violation(row)
176
- Violation.new do |v|
175
+ Eaternet::Lives_1_0::Violation.new do |v|
177
176
  v.business_id = business_id(row)
178
177
  v.date = Date.strptime(row['INSPECTION DATE'], '%m/%d/%Y')
179
178
  v.code = violation_code(row)
@@ -182,7 +181,7 @@ module Eaternet
182
181
  end
183
182
 
184
183
  def inspection(row)
185
- Inspection.new do |i|
184
+ Eaternet::Lives_1_0::Inspection.new do |i|
186
185
  i.business_id = business_id(row)
187
186
  i.date = Date.strptime(row['INSPECTION DATE'], '%m/%d/%Y')
188
187
  i.score = 100 - row['SCORE'].to_i
@@ -1,3 +1,3 @@
1
1
  module Eaternet
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+
3
+ require 'eaternet'
4
+ require 'eaternet/lives_1_0'
5
+
6
+ MULTCO_CASSETTE = 'multco'
7
+
8
+ class MultcoTest < Minitest::Test
9
+ @@multco = Eaternet::Multco.new
10
+
11
+ #
12
+ # Businesses
13
+ #
14
+
15
+ def test_businesses_returns_an_enumerator_of_business
16
+ VCR.use_cassette(MULTCO_CASSETTE) do
17
+ assert enumerable_of? Eaternet::Lives_1_0::Business, @@multco.businesses
18
+ end
19
+ end
20
+
21
+ def test_businesses_returns_lives_attributes
22
+ VCR.use_cassette(MULTCO_CASSETTE) do
23
+ b = @@multco.businesses.first
24
+ assert_equal '26013377', b.business_id
25
+ assert_equal '10 Barrel Brewing Company', b.name
26
+ assert_equal '1411 NW Flanders', b.address
27
+ assert_equal 'Portland', b.city
28
+ assert_equal '97209', b.postal_code
29
+ assert_equal 'OR', b.state
30
+ end
31
+ end
32
+
33
+ #
34
+ # Inspections
35
+ #
36
+
37
+ def test_inspections_returns_an_enumerable_of_inspection
38
+ VCR.use_cassette(MULTCO_CASSETTE) do
39
+ inspections = @@multco.inspections
40
+ assert enumerable_of? Eaternet::Lives_1_0::Inspection, inspections
41
+ end
42
+ end
43
+
44
+ def test_inspections_returns_lives_attributes
45
+ VCR.use_cassette(MULTCO_CASSETTE) do
46
+ i = @@multco.inspections.first(6).last
47
+ assert_equal '26004998', i.business_id
48
+ assert_equal Date.new(2015, 01, 13), i.date
49
+ assert_equal 97, i.score
50
+ end
51
+ end
52
+
53
+ #
54
+ # Violations
55
+ #
56
+
57
+ def test_violations_returns_an_enumerable_of_violation
58
+ VCR.use_cassette(MULTCO_CASSETTE) do
59
+ assert enumerable_of? Eaternet::Lives_1_0::Violation, @@multco.violations
60
+ end
61
+ end
62
+
63
+ def test_violations_returns_lives_attributes
64
+ VCR.use_cassette(MULTCO_CASSETTE) do
65
+ v = @@multco.violations.first
66
+ assert_equal '26004998', v.business_id
67
+ assert_equal Date.new(2015, 1, 13), v.date
68
+ assert_equal '4-302.12', v.code
69
+ assert_match /Temperature measuring devices/, v.description
70
+ end
71
+ end
72
+
73
+ #
74
+ # metadata
75
+ #
76
+
77
+ def test_implements_feed_info
78
+ assert_instance_of Eaternet::Lives_1_0::FeedInfo, @@multco.feed_info
79
+ end
80
+ end
@@ -51,21 +51,21 @@ class SnhdTest < Minitest::Test
51
51
  # Violations
52
52
  #
53
53
 
54
- def test_violations_returns_an_enumerable_of_violation
55
- VCR.use_cassette(SNHD_CASSETTE) do
56
- assert enumerable_of? Eaternet::Lives_1_0::Violation, @@snhd.violations
57
- end
58
- end
54
+ # def test_violations_returns_an_enumerable_of_violation
55
+ # VCR.use_cassette(SNHD_CASSETTE) do
56
+ # assert enumerable_of? Eaternet::Lives_1_0::Violation, @@snhd.violations
57
+ # end
58
+ # end
59
59
 
60
- def test_violations_returns_lives_attributes
61
- VCR.use_cassette(SNHD_CASSETTE) do
62
- v = @@snhd.violations.first
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
67
- end
68
- end
60
+ # def test_violations_returns_lives_attributes
61
+ # VCR.use_cassette(SNHD_CASSETTE) do
62
+ # v = @@snhd.violations.first
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
67
+ # end
68
+ # end
69
69
 
70
70
  #
71
71
  # metadata
data/test/test_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'minitest/autorun'
2
+ require 'minitest/perf'
2
3
  require 'pry'
3
4
  require 'webmock/minitest'
4
5
  require 'vcr'
@@ -7,6 +8,7 @@ VCR.configure do |c|
7
8
  c.cassette_library_dir = 'test/vcr_cassettes'
8
9
  c.hook_into :webmock
9
10
  c.ignore_hosts 'downloadtest.com'
11
+ c.default_cassette_options = { record: :new_episodes }
10
12
  end
11
13
 
12
14
  #
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.0
4
+ version: 1.0.1
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-05-31 00:00:00.000000000 Z
11
+ date: 2015-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-perf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pry
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +165,7 @@ dependencies:
151
165
  - !ruby/object:Gem::Version
152
166
  version: 3.2.21
153
167
  - !ruby/object:Gem::Dependency
154
- name: rubyzip
168
+ name: httparty
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - ">="
@@ -165,7 +179,35 @@ dependencies:
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
167
181
  - !ruby/object:Gem::Dependency
168
- name: httparty
182
+ name: mechanize
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: nokogiri
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rubyzip
169
211
  requirement: !ruby/object:Gem::Requirement
170
212
  requirements:
171
213
  - - ">="
@@ -197,6 +239,8 @@ files:
197
239
  - Rakefile
198
240
  - eaternet.gemspec
199
241
  - lib/eaternet.rb
242
+ - lib/eaternet/agencies/multco.rb
243
+ - lib/eaternet/agencies/multco_lib/misc.rb
200
244
  - lib/eaternet/agencies/nyc.rb
201
245
  - lib/eaternet/agencies/snhd.rb
202
246
  - lib/eaternet/agencies/snhd_config.rb
@@ -215,6 +259,7 @@ files:
215
259
  - lib/eaternet/validated_object.rb
216
260
  - lib/eaternet/version.rb
217
261
  - lib/ext/enumerator.rb
262
+ - test/eaternet/agencies/multco_test.rb
218
263
  - test/eaternet/agencies/nyc_test.rb
219
264
  - test/eaternet/agencies/snhd_prototype_test.rb
220
265
  - test/eaternet/agencies/snhd_test.rb
@@ -254,6 +299,7 @@ signing_key:
254
299
  specification_version: 4
255
300
  summary: Regional adapters for restaurant health scores
256
301
  test_files:
302
+ - test/eaternet/agencies/multco_test.rb
257
303
  - test/eaternet/agencies/nyc_test.rb
258
304
  - test/eaternet/agencies/snhd_prototype_test.rb
259
305
  - test/eaternet/agencies/snhd_test.rb