ullr 0.1.0 → 0.1.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.
- data/History.txt +4 -0
- data/README.md +2 -2
- data/lib/ullr/forecast.rb +52 -0
- data/lib/ullr/noaa.rb +205 -0
- data/version.txt +1 -1
- metadata +8 -6
data/History.txt
CHANGED
data/README.md
CHANGED
@@ -12,8 +12,8 @@ Features
|
|
12
12
|
Examples
|
13
13
|
--------
|
14
14
|
|
15
|
-
iheartsnow = Ullr::Forecast.new(:lat => 43.98, :lon => -121.68)
|
16
|
-
iheartsnow.get_nooa_forecast
|
15
|
+
* iheartsnow = Ullr::Forecast.new(:lat => 43.98, :lon => -121.68)
|
16
|
+
* iheartsnow.get_nooa_forecast
|
17
17
|
|
18
18
|
Run Tests
|
19
19
|
---------
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Ullr
|
2
|
+
class Forecast
|
3
|
+
require 'open-uri'
|
4
|
+
require 'ostruct'
|
5
|
+
attr_accessor :lat, :lon, :forecast_string, :noaa_endpoint, :data, :socket_error
|
6
|
+
NOAA_ENDPOINT = "http://forecast.weather.gov/MapClick.php?lat={{lat}}&lon={{lon}}&FcstType=dwml"
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
[:lat,:lon].each do |o|
|
10
|
+
raise(ArgumentError, "#{o.to_s} is required!") if !options[o] || !options[o].instance_of?(Float)
|
11
|
+
end
|
12
|
+
@lat = options[:lat]
|
13
|
+
@lon = options[:lon]
|
14
|
+
@noaa_endpoint = NOAA_ENDPOINT.gsub("{{lat}}",@lat.to_s).gsub("{{lon}}",@lon.to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_noaa_forecast
|
18
|
+
@socket_error = false
|
19
|
+
@data = []
|
20
|
+
begin
|
21
|
+
resp = open(@noaa_endpoint)
|
22
|
+
@forecast_string = resp.read
|
23
|
+
rescue SocketError
|
24
|
+
@socket_error = true
|
25
|
+
end
|
26
|
+
if !@socket_error
|
27
|
+
data = Ullr::NOAA::Data.parse(@forecast_string)
|
28
|
+
forecast = data.find{|o| o.type == 'forecast'}
|
29
|
+
if forecast
|
30
|
+
time_layout = forecast.time_layouts.find{|t| t.layout_key =~ /k-p12h/ }
|
31
|
+
time_layout.start_valid_times.each_with_index do |time,i|
|
32
|
+
params = forecast.parameters
|
33
|
+
word = params.worded_forecast.texts[i]
|
34
|
+
point = OpenStruct.new
|
35
|
+
point.start_time = time.period_start
|
36
|
+
point.name = time.period_name
|
37
|
+
point.pop = params.pops.values[i].value
|
38
|
+
point.text = word.value
|
39
|
+
point.snow = word.has_snow?
|
40
|
+
point.high_temperature = word.high_temperature
|
41
|
+
point.low_temperature = word.low_temperature
|
42
|
+
point.wind_direction = word.wind_direction
|
43
|
+
point.wind_speeds = word.wind_speeds
|
44
|
+
point.snow_estimate = word.snow_estimate
|
45
|
+
@data << point
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return @data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/ullr/noaa.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'happymapper'
|
2
|
+
module Ullr
|
3
|
+
module NOAA
|
4
|
+
class StartValidTime
|
5
|
+
include HappyMapper
|
6
|
+
tag 'start-valid-time'
|
7
|
+
content :period_start
|
8
|
+
attribute :'period-name', String
|
9
|
+
set_time = lambda{|ob| ob.period_start = DateTime.parse(ob.period_start) }
|
10
|
+
after_parse(&set_time)
|
11
|
+
end
|
12
|
+
|
13
|
+
class TimeLayout
|
14
|
+
include HappyMapper
|
15
|
+
tag 'time-layout'
|
16
|
+
attribute :'time-coordinate', String
|
17
|
+
attribute :summarization, String
|
18
|
+
element :'layout-key', String
|
19
|
+
has_many :start_valid_times, StartValidTime
|
20
|
+
end
|
21
|
+
|
22
|
+
class Value
|
23
|
+
include HappyMapper
|
24
|
+
content :value
|
25
|
+
end
|
26
|
+
|
27
|
+
class Temperature
|
28
|
+
include HappyMapper
|
29
|
+
tag 'temperature'
|
30
|
+
element :name, String
|
31
|
+
attribute :type, String
|
32
|
+
attribute :units, String
|
33
|
+
attribute :'time-layout', String
|
34
|
+
has_many :values, Value
|
35
|
+
end
|
36
|
+
|
37
|
+
class POP
|
38
|
+
include HappyMapper
|
39
|
+
tag 'probability-of-precipitation'
|
40
|
+
element :name, String
|
41
|
+
attribute :type, String
|
42
|
+
attribute :units, String
|
43
|
+
attribute :'time-layout', String
|
44
|
+
has_many :values, Value
|
45
|
+
end
|
46
|
+
|
47
|
+
class WeatherCondition
|
48
|
+
include HappyMapper
|
49
|
+
tag 'weather-conditions'
|
50
|
+
attribute :'weather-summary', String
|
51
|
+
end
|
52
|
+
|
53
|
+
class Weather
|
54
|
+
include HappyMapper
|
55
|
+
tag 'weather'
|
56
|
+
attribute :'time-layout', String
|
57
|
+
element :name, String
|
58
|
+
has_many :weather_conditions, WeatherCondition
|
59
|
+
end
|
60
|
+
|
61
|
+
class IconLink
|
62
|
+
include HappyMapper
|
63
|
+
tag 'icon-link'
|
64
|
+
content :url
|
65
|
+
end
|
66
|
+
|
67
|
+
class ConditionsIcon
|
68
|
+
include HappyMapper
|
69
|
+
tag 'conditions-icon'
|
70
|
+
attribute :'time-layout', String
|
71
|
+
element :name, String
|
72
|
+
has_many :icon_links, IconLink
|
73
|
+
end
|
74
|
+
|
75
|
+
class Text
|
76
|
+
include HappyMapper
|
77
|
+
tag 'text'
|
78
|
+
content :value
|
79
|
+
|
80
|
+
def has_snow?
|
81
|
+
if self.value =~ /snow/i
|
82
|
+
return true
|
83
|
+
else
|
84
|
+
return false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def snow_estimate
|
89
|
+
rng = ['0','0']
|
90
|
+
range = self.value.scan(/New snow accumulation of (0|[1-9]\d*) to (0|[1-9]\d*)/)
|
91
|
+
one = self.value.scan(/around an inch possible/)
|
92
|
+
if !one.empty?
|
93
|
+
rng = ['0','1']
|
94
|
+
elsif !range.empty?
|
95
|
+
rng = range.first
|
96
|
+
elsif self.has_snow?
|
97
|
+
rng = ['0','1']
|
98
|
+
end
|
99
|
+
return rng
|
100
|
+
end
|
101
|
+
|
102
|
+
def wind_direction
|
103
|
+
direction = self.value.scan(/ (\w*) wind [around|between]/i)
|
104
|
+
if !direction.empty?
|
105
|
+
direction = direction.first[0].downcase
|
106
|
+
else
|
107
|
+
direction = ''
|
108
|
+
end
|
109
|
+
return direction
|
110
|
+
end
|
111
|
+
|
112
|
+
def wind_speeds
|
113
|
+
rng = ['','']
|
114
|
+
range = self.value.scan(/ wind between (0|[1-9]\d*) and (0|[1-9]\d*)/i)
|
115
|
+
one = self.value.scan(/ wind around (0|[1-9]\d*)/i)
|
116
|
+
if !one.empty?
|
117
|
+
speed = one.first[0]
|
118
|
+
rng = [speed,speed]
|
119
|
+
elsif !range.empty?
|
120
|
+
rng = range.first
|
121
|
+
end
|
122
|
+
return rng
|
123
|
+
end
|
124
|
+
|
125
|
+
def high_temperature
|
126
|
+
high = ''
|
127
|
+
high_temp = self.value.scan(/high near (0|[1-9]\d*)/)
|
128
|
+
if !high_temp.empty?
|
129
|
+
high = high_temp.first[0]
|
130
|
+
end
|
131
|
+
return high
|
132
|
+
end
|
133
|
+
|
134
|
+
def low_temperature
|
135
|
+
low = ''
|
136
|
+
low_temp = self.value.scan(/low around (0|[1-9]\d*)/)
|
137
|
+
if !low_temp.empty?
|
138
|
+
low = low_temp.first[0]
|
139
|
+
end
|
140
|
+
return low
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class WordedForecast
|
145
|
+
include HappyMapper
|
146
|
+
tag 'wordedForecast'
|
147
|
+
attribute :'time-layout', String
|
148
|
+
attribute :dataSource, String
|
149
|
+
attribute :wordGenerator, String
|
150
|
+
element :name, String
|
151
|
+
has_many :texts, Text
|
152
|
+
end
|
153
|
+
|
154
|
+
class Parameters
|
155
|
+
include HappyMapper
|
156
|
+
tag 'parameters'
|
157
|
+
has_many :temperatures, Temperature
|
158
|
+
has_one :pops, POP
|
159
|
+
has_one :weather, Weather
|
160
|
+
has_one :conditions_icon, ConditionsIcon
|
161
|
+
has_one :worded_forecast, WordedForecast
|
162
|
+
end
|
163
|
+
|
164
|
+
class Point
|
165
|
+
include HappyMapper
|
166
|
+
tag 'point'
|
167
|
+
attribute :latitude, String
|
168
|
+
attribute :longitude, String
|
169
|
+
end
|
170
|
+
|
171
|
+
class City
|
172
|
+
include HappyMapper
|
173
|
+
tag 'city'
|
174
|
+
content :name
|
175
|
+
attribute :state, String
|
176
|
+
end
|
177
|
+
|
178
|
+
class Height
|
179
|
+
include HappyMapper
|
180
|
+
tag 'height'
|
181
|
+
attribute :datum, String
|
182
|
+
content :elevation
|
183
|
+
end
|
184
|
+
|
185
|
+
class Location
|
186
|
+
include HappyMapper
|
187
|
+
tag 'location'
|
188
|
+
element :'location-key', String
|
189
|
+
element :description, String
|
190
|
+
has_one :point, Point
|
191
|
+
has_one :city, City
|
192
|
+
has_one :height, Height
|
193
|
+
end
|
194
|
+
|
195
|
+
class Data
|
196
|
+
include HappyMapper
|
197
|
+
tag 'data'
|
198
|
+
has_one :parameters, Parameters
|
199
|
+
has_one :location, Location
|
200
|
+
has_many :time_layouts, TimeLayout
|
201
|
+
attribute :type, String
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ullr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-21 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: happymapper
|
16
|
-
requirement: &
|
16
|
+
requirement: &70189069609900 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.4.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70189069609900
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bones
|
27
|
-
requirement: &
|
27
|
+
requirement: &70189069635680 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 3.7.3
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70189069635680
|
36
36
|
description: ullr is a little gem that consumes NOAA weather xml for a given lat/long,
|
37
37
|
and returns an array of data with 12 hour forecasts along with some sugar to let
|
38
38
|
you know if any sugar will be falling from the sky.
|
@@ -50,6 +50,8 @@ files:
|
|
50
50
|
- Rakefile
|
51
51
|
- bin/ullr
|
52
52
|
- lib/ullr.rb
|
53
|
+
- lib/ullr/noaa.rb
|
54
|
+
- lib/ullr/forecast.rb
|
53
55
|
- spec/spec_helper.rb
|
54
56
|
- spec/ullr_spec.rb
|
55
57
|
- version.txt
|