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