eaternet 0.3.4 → 0.3.5
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/.yardopts +1 -0
- data/lib/eaternet/lives_1_0/adapter.rb +5 -5
- data/lib/eaternet/lives_1_0/business.rb +2 -1
- data/lib/eaternet/lives_1_0/feed_info.rb +48 -20
- data/lib/eaternet/lives_1_0/inspection.rb +12 -11
- data/lib/eaternet/lives_1_0/legend.rb +32 -6
- data/lib/eaternet/lives_1_0/legend_group.rb +12 -3
- data/lib/eaternet/lives_1_0/violation.rb +2 -0
- data/lib/eaternet/validated_object.rb +12 -8
- data/lib/eaternet/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c214305218f45f7fc0f0110e0a20262dc89c1b3
|
4
|
+
data.tar.gz: b3713a441f427f7157999e8152e82a36bc6ac30c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ace2d1b0f63390feee961ccdabede4f35792d746003726ba676d28f571ca18de77510a11e5f937e2f0f693297280eb2cb9cb3c58974a96bb7047d3e7145bff79
|
7
|
+
data.tar.gz: defe8a3e5cf85ccf3788e6fcb7a298a5e39261eb839b6834ab01f0cda797302926ca89435da362106b44a7e54c5527c9e369877e853e81ee2666fed2504ff7fe
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --name-tag required:"Required"
|
@@ -4,31 +4,31 @@ module Eaternet
|
|
4
4
|
# and optionally {#violations}, {#feed_info}, and {#legends} to
|
5
5
|
# implement a custom Lives 1.0 data source adapter.
|
6
6
|
class Adapter
|
7
|
-
#
|
7
|
+
# @required Yes
|
8
8
|
# @return [Enumerable<Business>]
|
9
9
|
def businesses
|
10
10
|
fail 'Override this to return an Enumerable of Business'
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
13
|
+
# @required Yes
|
14
14
|
# @return [Enumerable<Inspection>]
|
15
15
|
def inspections
|
16
16
|
fail 'Override this to return an Enumerable of Inspection'
|
17
17
|
end
|
18
18
|
|
19
|
-
#
|
19
|
+
# @required No
|
20
20
|
# @return [Enumerable<Violation>]
|
21
21
|
def violations
|
22
22
|
fail 'Optionally override this to return an Enumerable of Violation'
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# @required No
|
26
26
|
# @return [FeedInfo]
|
27
27
|
def feed_info
|
28
28
|
fail 'Optionally override this to return a FeedInfo'
|
29
29
|
end
|
30
30
|
|
31
|
-
#
|
31
|
+
# @required No
|
32
32
|
# @return [Enumerable<Legend>]
|
33
33
|
def legends
|
34
34
|
fails 'Optionally override this to return an Enumerable of Legend'
|
@@ -48,7 +48,8 @@ module Eaternet
|
|
48
48
|
# information. For example: +14159083801
|
49
49
|
# @return [String]
|
50
50
|
#
|
51
|
-
# @see http://www.yelp.com/healthscores#businesses LIVES/Business
|
51
|
+
# @see http://www.yelp.com/healthscores#businesses LIVES / Business
|
52
|
+
# specification
|
52
53
|
class Business < ValidatedObject
|
53
54
|
attr_accessor :business_id, :name, :address, :city, :state,
|
54
55
|
:postal_code, :latitude, :longitude, :phone_number
|
@@ -2,32 +2,60 @@ require 'eaternet/validated_object'
|
|
2
2
|
|
3
3
|
module Eaternet
|
4
4
|
module Lives_1_0
|
5
|
+
# Contains info about the feed itself.
|
6
|
+
#
|
5
7
|
# @see http://www.yelp.com/healthscores#feed_info LIVES / Feed Information
|
8
|
+
# specification
|
6
9
|
class FeedInfo < ValidatedObject
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
# This regular expression for checking email addresses is based on one
|
11
|
+
# from one of Ryan Bates’ excellent screencasts.
|
10
12
|
# See http://railscasts.com/episodes/211-validations-in-rails-3
|
11
13
|
EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
12
14
|
URL_REGEX = %r{\Ahttps?:/}
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
validates :
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
# Date that the feed was generated.
|
17
|
+
#
|
18
|
+
# @required Yes
|
19
|
+
# @return [Date]
|
20
|
+
attr_accessor :feed_date
|
21
|
+
validates :feed_date, presence: true, type: Date
|
22
|
+
|
23
|
+
# Version of the LIVES specification used to generate this feed.
|
24
|
+
# For example ‘0.4.1’.
|
25
|
+
#
|
26
|
+
# @required Yes
|
27
|
+
# @return [String]
|
28
|
+
attr_accessor :feed_version
|
29
|
+
validates :feed_version, presence: true, type: String
|
30
|
+
|
31
|
+
# Name of the municipality providing this feed. For example
|
32
|
+
# ‘San Francisco’ or ‘Multnomah County’.
|
33
|
+
#
|
34
|
+
# @required Yes
|
35
|
+
# @return [String]
|
36
|
+
attr_accessor :municipality_name
|
37
|
+
validates :municipality_name, presence: true, type: String
|
38
|
+
|
39
|
+
# URL of the publishing municipality’s website.
|
40
|
+
#
|
41
|
+
# @required No
|
42
|
+
# @return [String]
|
43
|
+
attr_accessor :municipality_url
|
44
|
+
validates :municipality_url,
|
45
|
+
type: String,
|
46
|
+
format: { with: URL_REGEX },
|
47
|
+
allow_nil: true
|
48
|
+
|
49
|
+
# Email address of the person to contact regarding invalid data in
|
50
|
+
# this feed.
|
51
|
+
#
|
52
|
+
# @required No
|
53
|
+
# @return [String]
|
54
|
+
attr_accessor :contact_email
|
55
|
+
validates :contact_email,
|
56
|
+
type: String,
|
57
|
+
format: { with: EMAIL_REGEX },
|
58
|
+
allow_nil: true
|
31
59
|
end
|
32
60
|
end
|
33
61
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'eaternet/validated_object'
|
3
2
|
|
4
3
|
module Eaternet
|
5
4
|
module Lives_1_0
|
6
5
|
# Information about an inspectors’ visit to a businesses.
|
6
|
+
#
|
7
|
+
# @todo Clean up the Yard doc.
|
7
8
|
# @see http://www.yelp.com/healthscores#inspections LIVES / Inspections
|
9
|
+
# specification
|
8
10
|
class Inspection < ValidatedObject
|
9
11
|
ZERO_TO_ONE_HUNDRED_AND_BLANK = (0..100).to_a + ['']
|
10
12
|
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# Unique identifier of the business for which this inspection
|
14
|
+
# was done. Required.
|
15
|
+
#
|
16
|
+
# @return [String]
|
15
17
|
attr_accessor :business_id
|
16
18
|
validates :business_id,
|
17
19
|
type: String,
|
@@ -24,8 +26,8 @@ module Eaternet
|
|
24
26
|
# associated score. (For example, some municipalities don’t associate
|
25
27
|
# a follow-up inspection with a score.)
|
26
28
|
# @return [Integer] if it's a scored inspection
|
27
|
-
# @return [String] if it's an un-scored inspection, then the return
|
28
|
-
# will be an empty string.
|
29
|
+
# @return [String] if it's an un-scored inspection, then the return
|
30
|
+
# value will be an empty string.
|
29
31
|
attr_accessor :score
|
30
32
|
validates :score,
|
31
33
|
inclusion: { in: ZERO_TO_ONE_HUNDRED_AND_BLANK },
|
@@ -50,15 +52,14 @@ module Eaternet
|
|
50
52
|
# @return [String]
|
51
53
|
attr_accessor :description
|
52
54
|
|
53
|
-
validates :type,
|
54
|
-
inclusion: { in: %w(initial routine followup complaint) },
|
55
|
-
allow_nil: true
|
56
|
-
|
57
55
|
# @!attribute [rw] type
|
58
56
|
# String representing the type of inspection. Must be (initial,
|
59
57
|
# routine, followup, complaint).
|
60
58
|
# @return [String]
|
61
59
|
attr_accessor :type
|
60
|
+
validates :type,
|
61
|
+
inclusion: { in: %w(initial routine followup complaint) },
|
62
|
+
allow_nil: true
|
62
63
|
|
63
64
|
# @return [String]
|
64
65
|
def to_s
|
@@ -2,14 +2,40 @@ require 'eaternet/validated_object'
|
|
2
2
|
|
3
3
|
module Eaternet
|
4
4
|
module Lives_1_0
|
5
|
+
# Legends are mappings from score ranges to human-readable descriptions of
|
6
|
+
# those scores. Municipalities can use these to communicate the way scores
|
7
|
+
# are traditionally presented. For example, 0-60 may map to ‘Fail’ or 95-100
|
8
|
+
# may map to ‘A+’. The provided ranges in {#minimum_score} and
|
9
|
+
# {#maximum_score} must cover the entire 0-100 span without overlap. For
|
10
|
+
# scores at the edge of two ranges, the greater range will be used. For
|
11
|
+
# example, if 80-90 is a ‘B’ and 90-100 is an ‘A’, a score of 90 would be an
|
12
|
+
# ‘A’. These are optional.
|
13
|
+
#
|
14
|
+
# @see LegendGroup Lives_1_0::LegendGroup, which enforces the 0–100 span and
|
15
|
+
# checks for overlap.
|
16
|
+
# @see http://www.yelp.com/healthscores#legend LIVES / Legend specification
|
5
17
|
class Legend < ValidatedObject
|
6
|
-
|
18
|
+
# Minimum score that can be classified with this description.
|
19
|
+
#
|
20
|
+
# @required Yes
|
21
|
+
# @return [Integer]
|
22
|
+
attr_accessor :minimum_score
|
23
|
+
validates :minimum_score, inclusion: { in: (0..100) }
|
7
24
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
25
|
+
# Maximum score that can be classified with this description.
|
26
|
+
#
|
27
|
+
# @required Yes
|
28
|
+
# @return [Integer]
|
29
|
+
attr_accessor :maximum_score
|
30
|
+
validates :maximum_score, inclusion: { in: (0..100) }
|
31
|
+
|
32
|
+
# Formatted version of the score in the format typically presented by the
|
33
|
+
# municipality. For example ‘A’ or ‘Pass’.
|
34
|
+
#
|
35
|
+
# @required Yes
|
36
|
+
# @return [String]
|
37
|
+
attr_accessor :description
|
38
|
+
validates :description, presence: true, type: String
|
13
39
|
end
|
14
40
|
end
|
15
41
|
end
|
@@ -3,9 +3,16 @@ require 'eaternet/validated_object'
|
|
3
3
|
|
4
4
|
module Eaternet
|
5
5
|
module Lives_1_0
|
6
|
-
# A container for all the Legends in the data set. Performs
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# A container for all the Legends in the data set. Performs validation on
|
7
|
+
# the whole set of Legends to ensure they cover the entire range of scores
|
8
|
+
# and do not overlap, as specified:
|
9
|
+
#
|
10
|
+
# "The provided ranges [...] must cover the entire 0–100 span without
|
11
|
+
# overlap. For scores at the edge of two ranges, the greater range will be
|
12
|
+
# used."
|
13
|
+
#
|
14
|
+
# @see http://www.yelp.com/healthscores#legend LIVES / Score Legend
|
15
|
+
# specification
|
9
16
|
class LegendGroup < ValidatedObject
|
10
17
|
attr_accessor :legends
|
11
18
|
|
@@ -13,6 +20,8 @@ module Eaternet
|
|
13
20
|
#
|
14
21
|
# 1. Are of the class, Legend
|
15
22
|
# 2. Cover the range of scores from 0-100 without overlap
|
23
|
+
#
|
24
|
+
# @todo: Refactor
|
16
25
|
class ComprehensiveValidator < ActiveModel::EachValidator
|
17
26
|
def validate_each(record, attribute, legends)
|
18
27
|
scores = (0..100).to_a
|
@@ -2,7 +2,9 @@ require 'eaternet/validated_object'
|
|
2
2
|
|
3
3
|
module Eaternet
|
4
4
|
module Lives_1_0
|
5
|
+
# @todo Document
|
5
6
|
# @see http://www.yelp.com/healthscores#violations LIVES / Violations
|
7
|
+
# specification
|
6
8
|
class Violation < ValidatedObject
|
7
9
|
attr_accessor :business_id, :date, :code, :description
|
8
10
|
|
@@ -8,7 +8,7 @@ module Eaternet
|
|
8
8
|
# to create self-validating Plain Old Ruby objects. This is especially useful for
|
9
9
|
# data validation when importing from CSV.
|
10
10
|
#
|
11
|
-
# @example
|
11
|
+
# @example Writing a self-validating object
|
12
12
|
# class Dog < Eaternet::ValidatedObject
|
13
13
|
# attr_accessor :name, :birthday
|
14
14
|
#
|
@@ -16,19 +16,22 @@ module Eaternet
|
|
16
16
|
# validates :birthday, type: Date, allow_nil: true
|
17
17
|
# end
|
18
18
|
#
|
19
|
+
# @example Instantiating and automatically validating
|
19
20
|
# # The dog1 instance is validated at the end of instantiation. Here, it succeeds
|
20
|
-
# # without exception
|
21
|
+
# # without exception.
|
21
22
|
# dog1 = Dog.new do |d|
|
22
23
|
# d.name = 'Spot'
|
23
24
|
# end
|
24
25
|
#
|
25
|
-
#
|
26
|
+
# # We can also explicitly test for validity
|
27
|
+
# dog1.valid? # => true
|
26
28
|
#
|
27
29
|
# dog1.birthday = Date.new(2015, 1, 23)
|
28
|
-
#
|
30
|
+
# dog1.valid? # => true
|
29
31
|
#
|
32
|
+
# @example Making an instance invalid
|
30
33
|
# dog1.birthday = '2015-01-23'
|
31
|
-
#
|
34
|
+
# dog1.valid? # => false
|
32
35
|
# dog1.check_validations! # => ArgumentError: birthday is not of class Date
|
33
36
|
#
|
34
37
|
# @see Eaternet::ValidatedObject::TypeValidator
|
@@ -55,15 +58,16 @@ module Eaternet
|
|
55
58
|
fail ArgumentError, errors.messages.inspect if invalid?
|
56
59
|
end
|
57
60
|
|
58
|
-
#
|
59
|
-
#
|
61
|
+
# A custom validator which ensures an object is a certain class.
|
62
|
+
# It's here as a nested class in {ValidatedObject} for easy access by subclasses.
|
60
63
|
#
|
61
|
-
# @example
|
64
|
+
# @example Ensure that weight is a floating point number
|
62
65
|
# class Dog < ValidatedObject
|
63
66
|
# attr_accessor :weight
|
64
67
|
# validates :weight, type: Float
|
65
68
|
# end
|
66
69
|
class TypeValidator < ActiveModel::EachValidator
|
70
|
+
# @return [nil]
|
67
71
|
def validate_each(record, attribute, value)
|
68
72
|
return if value.class == options[:with]
|
69
73
|
|
data/lib/eaternet/version.rb
CHANGED
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: 0.3.
|
4
|
+
version: 0.3.5
|
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-
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- ".gitignore"
|
176
176
|
- ".inch.yml"
|
177
177
|
- ".travis.yml"
|
178
|
+
- ".yardopts"
|
178
179
|
- Gemfile
|
179
180
|
- Guardfile
|
180
181
|
- LICENSE.txt
|