eaternet 1.0.0 → 1.0.1

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: 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