sandy 0.0.5 → 0.0.6

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.
@@ -1,15 +1,21 @@
1
+ require 'tzinfo'
1
2
  module Sandy::Provider
2
3
  module LIPA
3
4
  class Report
4
- attr_reader :regions, :neighborhoods
5
+ include Sandy::Provider::StormCenter
6
+ attr_reader :areas
5
7
 
6
8
  def initialize
7
9
  raw_report = HTTParty.get(lipa_url, format: :xml)
8
10
  area_hash = raw_report.fetch("root").fetch("curr_custs_aff")["areas"]["area"]["areas"].first[1]
9
- @regions = regions_from_report(area_hash)
10
- @neighborhoods = neighborhoods_from_report(area_hash)
11
+
12
+ @areas = recursive_fetch_areas(
13
+ area_hash,
14
+ ->(area) { area.fetch("areas", {}).fetch("area", nil) }
15
+ )
16
+
11
17
  rescue
12
- raise LoadError, "ConEd reponse was not recognizable."
18
+ raise LoadError, "LIPA response was not recognizable."
13
19
  end
14
20
 
15
21
  private
@@ -17,47 +23,16 @@ module Sandy::Provider
17
23
  def lipa_url
18
24
  base_uri = "http://stormcenter.lipower.org"
19
25
 
20
- #FIXME: verify timezone is in NYC zone
21
- time = Time.now.to_i
26
+ tz = TZInfo::Timezone.get('America/New_York')
27
+ time = tz.now.to_i
22
28
  directory_url = "#{base_uri}/data/interval_generation_data/metadata.xml?timestamp=#{time}"
23
29
  response = HTTParty.get(directory_url, format: :xml)
24
30
  directory = response.parsed_response.fetch("root").fetch("directory")
25
31
  "#{base_uri}/data/interval_generation_data/#{directory}/data.xml?timestamp=#{time}"
26
32
  end
27
33
 
28
- def regions_from_report(areas)
29
- areas.collect do |area|
30
- Sandy::Area.new(area.fetch("custs_out"), area.fetch("area_name"),
31
- { estimated_recovery_time: area["etr"],
32
- total_customers: area["total_custs"] })
33
-
34
- end
35
- end
36
-
37
- def neighborhoods_from_report(areas_hash)
38
- neighborhoods = []
39
- areas_hash.each do |region|
40
- region["areas"].each do |sub_region|
41
- sub_sub_regions = sub_region[1]
42
- sub_sub_regions.each do |sub_sub_region|
43
- begin
44
- hoods = sub_sub_region["areas"]["area"]
45
- rescue
46
- # FIXME: raise warning if any region is empty
47
- next
48
- end
49
- hoods.each do |hood|
50
- total = hood.fetch("total_custs").to_i
51
- affected = hood.fetch("custs_out").to_i
52
- name = hood.fetch("area_name")
53
- region = sub_sub_region.fetch("area_name")
54
-
55
- neighborhoods << Sandy::Area.new(affected, name, { region: region, total_customers: total})
56
- end
57
- end
58
- end
59
- end
60
- neighborhoods
34
+ def path
35
+ File.dirname(__FILE__)
61
36
  end
62
37
  end
63
38
  end
@@ -1,3 +1,4 @@
1
+ require "sandy/providers/storm_center"
1
2
  require "sandy/providers/lipa/report"
2
3
  require "sandy/area"
3
4
  require "httparty"
@@ -0,0 +1,43 @@
1
+ ---
2
+ bergen:
3
+ :latitude: '40.9262762'
4
+ :longitude: '-74.07701'
5
+ burlington:
6
+ :latitude: '40.0647377'
7
+ :longitude: '-74.8409196'
8
+ camden:
9
+ :latitude: '39.9259463'
10
+ :longitude: '-75.1196199'
11
+ essex:
12
+ :latitude: '40.7947466'
13
+ :longitude: '-74.2648829'
14
+ gloucester:
15
+ :latitude: '39.8025'
16
+ :longitude: '-75.0447222'
17
+ hudson:
18
+ :latitude: '40.7453199'
19
+ :longitude: '-74.0535126'
20
+ hunterdon:
21
+ :latitude: '40.5669515'
22
+ :longitude: '-74.9208772'
23
+ mercer:
24
+ :latitude: '40.3028533'
25
+ :longitude: '-74.7337069'
26
+ middlesex:
27
+ :latitude: '40.572603'
28
+ :longitude: '-74.4926541'
29
+ monmouth:
30
+ :latitude: '40.2589455'
31
+ :longitude: '-74.123996'
32
+ morris:
33
+ :latitude: '40.8336038'
34
+ :longitude: '-74.5463282'
35
+ passaic:
36
+ :latitude: '40.8567662'
37
+ :longitude: '-74.1284764'
38
+ somerset:
39
+ :latitude: '40.5292099'
40
+ :longitude: '-74.6400432'
41
+ union:
42
+ :latitude: '40.6975898'
43
+ :longitude: '-74.2631635'
@@ -0,0 +1,54 @@
1
+ require 'xml'
2
+
3
+ module Sandy::Provider
4
+ module PSEG
5
+ class Report
6
+ include Sandy::Provider::CoordinateCache
7
+
8
+ attr_reader :areas
9
+
10
+ def initialize
11
+ parser = XML::Parser.new
12
+ parser.string = HTTParty.get(pseg_url).to_s
13
+ raw_report = parser.parse
14
+
15
+ @areas = parse raw_report
16
+
17
+ rescue
18
+ raise LoadError, "PSEG response was not recognizable."
19
+ end
20
+
21
+ private
22
+
23
+ def parse raw_report
24
+ arr = []
25
+ raw_report.find('//ms:polygon').each do |p|
26
+ begin
27
+ name = p.find_first('ms:county').content.to_s
28
+ customers_affected = p.find_first('ms:outage').content.to_s
29
+
30
+ latitude, longitude = cached_coordinates_for name.downcase
31
+
32
+ options = {
33
+ :latitude => latitude,
34
+ :longitude => longitude
35
+ }
36
+ arr << Sandy::Area.new(customers_affected, name, options)
37
+ rescue
38
+ # FIXME: raise warning if any region is empty.
39
+ next
40
+ end
41
+ end
42
+ arr
43
+ end
44
+
45
+ def pseg_url
46
+ 'http://www.pseg.com/outagemap/Customer%20Outage%20Application/Web%20Pages/GML/State.gml'
47
+ end
48
+
49
+ def path
50
+ File.dirname(__FILE__)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ require "sandy/providers/pseg/report"
2
+ require "sandy/area"
3
+ require "httparty"
4
+ require "json"
5
+
6
+ module Sandy::Provider
7
+ module PSEG
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ module Sandy::Provider
2
+ module StormCenter
3
+ include Sandy::Provider::CoordinateCache
4
+
5
+ def recursive_fetch_areas report_areas, sub_select_func, parent=nil
6
+ if report_areas
7
+ arr = []
8
+ report_areas.each do |report_area|
9
+ begin
10
+
11
+ latitude, longitude = cached_coordinates_for(report_area['area_name'].downcase)
12
+
13
+ options = {
14
+ parent: parent,
15
+ total_customers: report_area.fetch("total_custs", 0).to_i,
16
+ estimated_recovery_time: report_area.fetch("etr", nil),
17
+ latitude: latitude,
18
+ longitude: longitude,
19
+ children: recursive_fetch_areas(sub_select_func.call(report_area), sub_select_func, report_area)
20
+ }
21
+
22
+ arr.push Sandy::Area.new(report_area.fetch("custs_out", 0).to_i, sanitize_name(report_area.fetch("area_name", nil)), options)
23
+ rescue
24
+ # FIXME: raise warning if any region is empty.
25
+ next
26
+ end
27
+ end
28
+ arr
29
+ else
30
+ []
31
+ end
32
+ end
33
+
34
+ def sanitize_name str
35
+ str.split(' ').map {|w| w.downcase.capitalize }.join(' ')
36
+ end
37
+
38
+ end
39
+ end
data/lib/sandy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sandy
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/sandy.gemspec CHANGED
@@ -18,7 +18,10 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ["lib"]
19
19
 
20
20
  gem.add_dependency("httparty", "~> 0.9.0")
21
- gem.add_development_dependency("rake")
21
+ gem.add_dependency("tzinfo", "~> 0.3.35")
22
+ gem.add_dependency("libxml-ruby", "~> 2.3.3")
23
+
24
+ gem.add_development_dependency("rake")
22
25
  gem.add_development_dependency("rspec", "~> 2.11.0")
23
26
  gem.add_development_dependency("webmock", "~> 1.8.11")
24
27
  gem.add_development_dependency("vcr", "~> 2.3.0")
data/spec/area_spec.rb CHANGED
@@ -9,6 +9,26 @@ describe Sandy::Area do
9
9
  it { should == customers_affected }
10
10
  end
11
11
 
12
+ describe "#to_s" do
13
+ subject { Sandy::Area.new(customers_affected, "Manhattan").to_s }
14
+ it { should == "Manhattan" }
15
+ end
16
+
17
+ describe "#to_json" do
18
+ let(:parent) { Sandy::Area.new(0, "Manhattan") }
19
+ subject { Sandy::Area.new(customers_affected,
20
+ nil, { parent: parent }).to_json }
21
+
22
+ it { should == {"name" => nil,
23
+ "customers_affected" => customers_affected,
24
+ "parent" => parent.name,
25
+ "total_customers" => nil,
26
+ "latitude" => nil,
27
+ "longitude" => nil,
28
+ "estimated_recovery_time" => nil,
29
+ "children" => [] }.to_json }
30
+ end
31
+
12
32
  context "with an area name" do
13
33
  let(:area_name) { "Battery Park" }
14
34
  describe "#name" do
@@ -19,7 +39,7 @@ describe Sandy::Area do
19
39
 
20
40
  context "with a region name" do
21
41
  describe "#parent_region" do
22
- subject { Sandy::Area.new(customers_affected, nil, { region: "Manhattan" }).region }
42
+ subject { Sandy::Area.new(customers_affected, nil, { parent: "Manhattan" }).parent }
23
43
  it { should == "Manhattan" }
24
44
  end
25
45
  end
@@ -5,19 +5,19 @@ describe Sandy::Provider::ConEd::Report do
5
5
  context "with an empty response" do
6
6
  before { HTTParty.stub(:get).and_return("") }
7
7
  it "raises an informative error" do
8
- expect { Sandy::Provider::ConEd::Report.new }.to raise_error(LoadError, "ConEd reponse was not recognizable.")
8
+ expect { Sandy::Provider::ConEd::Report.new }.to raise_error(LoadError, "ConEd response was not recognizable.")
9
9
  end
10
10
  end
11
11
  end
12
12
 
13
- describe "#regions" do
14
- subject { Sandy::Provider::ConEd::Report.new.regions }
15
- it { should be_an_instance_of Array }
16
- it { should_not be_empty }
13
+ describe "#to_json" do
14
+ it 'has an array of areas' do
15
+ Sandy::Provider::ConEd::Report.new.to_json["areas"].should be_an_instance_of Array
16
+ end
17
17
  end
18
18
 
19
- describe "#neighborhoods" do
20
- subject { Sandy::Provider::ConEd::Report.new.neighborhoods }
19
+ describe "#areas" do
20
+ subject { Sandy::Provider::ConEd::Report.new.areas }
21
21
  it { should be_an_instance_of Array }
22
22
  it { should_not be_empty }
23
23
  end
@@ -5,19 +5,13 @@ describe Sandy::Provider::LIPA::Report do
5
5
  context "with an empty response" do
6
6
  before { HTTParty.stub(:get).and_return("") }
7
7
  it "raises an informative error" do
8
- expect { Sandy::Provider::LIPA::Report.new }.to raise_error(LoadError, "ConEd reponse was not recognizable.")
8
+ expect { Sandy::Provider::LIPA::Report.new }.to raise_error(LoadError, "LIPA response was not recognizable.")
9
9
  end
10
10
  end
11
11
  end
12
12
 
13
- describe "#regions" do
14
- subject { Sandy::Provider::LIPA::Report.new.regions }
15
- it { should be_an_instance_of Array }
16
- it { should_not be_empty }
17
- end
18
-
19
- describe "#neighborhoods" do
20
- subject { Sandy::Provider::LIPA::Report.new.neighborhoods }
13
+ describe "#areas" do
14
+ subject { Sandy::Provider::LIPA::Report.new.areas }
21
15
  it { should be_an_instance_of Array }
22
16
  it { should_not be_empty }
23
17
  end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe Sandy::Provider::PSEG::Report do
4
+ describe ".initialize" do
5
+ context "with an empty response" do
6
+ before { HTTParty.stub(:get).and_return("") }
7
+ it "raises an informative error" do
8
+ expect { Sandy::Provider::PSEG::Report.new }.to raise_error(LoadError, "PSEG response was not recognizable.")
9
+ end
10
+ end
11
+ end
12
+
13
+ describe "#areas" do
14
+ subject { Sandy::Provider::PSEG::Report.new.areas }
15
+ it { should be_an_instance_of Array }
16
+ it { should_not be_empty }
17
+ end
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sandy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-04 00:00:00.000000000 Z
12
+ date: 2012-11-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 0.9.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: tzinfo
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.3.35
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.3.35
46
+ - !ruby/object:Gem::Dependency
47
+ name: libxml-ruby
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.3
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.3
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: rake
32
64
  requirement: !ruby/object:Gem::Requirement
@@ -109,14 +141,22 @@ files:
109
141
  - lib/sandy/area.rb
110
142
  - lib/sandy/provider.rb
111
143
  - lib/sandy/providers/coned.rb
144
+ - lib/sandy/providers/coned/gps_data.yml
112
145
  - lib/sandy/providers/coned/report.rb
146
+ - lib/sandy/providers/coordinate_cache.rb
113
147
  - lib/sandy/providers/lipa.rb
148
+ - lib/sandy/providers/lipa/gps_data.yml
114
149
  - lib/sandy/providers/lipa/report.rb
150
+ - lib/sandy/providers/pseg.rb
151
+ - lib/sandy/providers/pseg/gps_data.yml
152
+ - lib/sandy/providers/pseg/report.rb
153
+ - lib/sandy/providers/storm_center.rb
115
154
  - lib/sandy/version.rb
116
155
  - sandy.gemspec
117
156
  - spec/area_spec.rb
118
157
  - spec/providers/coned/report_spec.rb
119
158
  - spec/providers/lipa/report_spec.rb
159
+ - spec/providers/pseg/pseg_spec.rb
120
160
  - spec/spec_helper.rb
121
161
  homepage: http://www.github.com/ckundo/sandy
122
162
  licenses: []
@@ -138,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
178
  version: '0'
139
179
  requirements: []
140
180
  rubyforge_project:
141
- rubygems_version: 1.8.24
181
+ rubygems_version: 1.8.19
142
182
  signing_key:
143
183
  specification_version: 3
144
184
  summary: Power outage data for ConEd in NYC
@@ -146,5 +186,6 @@ test_files:
146
186
  - spec/area_spec.rb
147
187
  - spec/providers/coned/report_spec.rb
148
188
  - spec/providers/lipa/report_spec.rb
189
+ - spec/providers/pseg/pseg_spec.rb
149
190
  - spec/spec_helper.rb
150
191
  has_rdoc: