noaaer 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in noaaer.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise 'hi'
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'noaaer')
5
+
6
+ begin
7
+ file = File.open(File.join(File.dirname(__FILE__), '..', 'data', 'stations.yml'), 'w')
8
+ puts 'Downloading station list from NOAA...'
9
+ doc = Noaaer::HttpService.new.get_station_list
10
+ puts 'Converting station list to YAML...'
11
+ Noaaer::StationWriter.new(doc).write(file)
12
+ puts "Done."
13
+ end
@@ -0,0 +1,185 @@
1
+ module Noaaer
2
+ #
3
+ # Representation of the current conditions for a given observation point.
4
+ #
5
+ class CurrentConditions
6
+
7
+ class <<self
8
+ private :new
9
+
10
+ def from_xml(doc) #:nodoc:
11
+ new(doc)
12
+ end
13
+ end
14
+
15
+ def initialize(doc) #:notnew:
16
+ @doc = doc
17
+ end
18
+
19
+ #
20
+ # Time object containing the time at which these conditions were observed at the NOAA station
21
+ #
22
+ def observed_at
23
+ @observed_at ||= Time.parse(text_from_node('observation_time_rfc822'))
24
+ end
25
+
26
+ #
27
+ # Text description of the current weather conditions, e.g. "Fair"
28
+ #
29
+ def weather_description
30
+ @weather_description ||= text_from_node('weather')
31
+ end
32
+ alias_method :weather_summary, :weather_description
33
+
34
+ #
35
+ # NWS code representing weather type. This distills the #weather_description
36
+ # into one of a much more manageable set of possibilities. Possible values are:
37
+ #
38
+ # - <code>:skc</code> - Clear
39
+ # - <code>:wind</code> - Windy
40
+ # - <code>:few</code> - A Few Clouds
41
+ # - <code>:sct</code> - Partly Cloudy
42
+ # - <code>:bkn</code> - Mostly Cloudy
43
+ # - <code>:ovc</code> - Overcast
44
+ # - <code>:ra1</code> - Light Rain
45
+ # - <code>:ra</code> - Rain
46
+ # - <code>:shra</code> - Rain Showers
47
+ # - <code>:tsra</code> - Thunderstorms
48
+ # - <code>:ip</code> - Hail
49
+ # - <code>:fzra</code> - Freezing Rain
50
+ # - <code>:mix</code> - Wintry Mix
51
+ # - <code>:sn</code> - Snow
52
+ # - <code>:fg</code> - Fog
53
+ # - <code>:smoke</code> - Smoke
54
+ # - <code>:dust</code> - Dust/Sand
55
+ # - <code>:mist</code> - Haze
56
+ # - <code>:svrtsra</code> - Tornado
57
+ # - <code>:fzrara</code> - Freezing Rain/Rain
58
+ # - <code>:raip</code> - Rain/Hail
59
+ # - <code>:rasn</code> - Rain/Snow
60
+ # - <code>:hi_shwrs</code> - Showers in Vicinity
61
+ # - <code>:hi_tsra</code> - Thunderstorm in Vicinity
62
+ #
63
+ # See http://www.weather.gov/xml/current_obs/weather.php for the NWS's list of possible
64
+ # descriptions and their type codes.
65
+ #
66
+ def weather_type_code
67
+ @weather_type_code ||= text_from_node('icon_url_name').gsub(/^n|\.jpg$/, '').to_sym
68
+ end
69
+
70
+ #
71
+ # Return the NWS image URL for the current weather as string
72
+ #
73
+ def image_url
74
+ @image_url ||= "#{text_from_node('icon_url_base')}#{text_from_node('icon_url_name')}"
75
+ end
76
+
77
+ #
78
+ # The current temperature in the requested units.
79
+ #
80
+ # conditions.temperature #=> temperature in fahrenheit
81
+ # conditions.temperature(:c) #=> temperature in celsius
82
+ # conditions.temperature(:kelvin) #=> anything else raises an exception
83
+ #
84
+ def temperature(unit = :f)
85
+ text_from_node_with_unit('temp', unit, :f, :c).to_i
86
+ end
87
+
88
+ #
89
+ # The current relative humidity percentage (0-100)
90
+ #
91
+ def relative_humidity
92
+ text_from_node('relative_humidity').to_i
93
+ end
94
+
95
+ #
96
+ # The current cardinal or ordinal direction that the wind is coming from (e.g., "Northwest")
97
+ #
98
+ def wind_direction
99
+ text_from_node('wind_dir')
100
+ end
101
+
102
+ #
103
+ # The current direction that the wind is coming from degrees (e.g. 330)
104
+ #
105
+ def wind_degrees
106
+ text_from_node('wind_degrees').to_i
107
+ end
108
+
109
+ #
110
+ # The current wind speed in miles per hour as a float (e.g., 3.45)
111
+ #
112
+ def wind_speed
113
+ text_from_node('wind_mph').to_f
114
+ end
115
+
116
+ #
117
+ # The current wind gust in miles per hour as a float, or nil if none
118
+ #
119
+ def wind_gust
120
+ text_from_node('wind_gust_mph').to_f
121
+ end
122
+
123
+ #
124
+ # The current barometric pressure
125
+ #
126
+ # conditions.pressure #=> pressure in inches
127
+ # conditions.pressure(:mb) #=> pressure in millibars
128
+ # conditions.pressure(:psi) #=> anything else raises an exception
129
+ #
130
+ def pressure(unit = :in)
131
+ text_from_node_with_unit('pressure', unit, :in, :mb).to_f
132
+ end
133
+
134
+ #
135
+ # The current dew point.
136
+ #
137
+ # conditions.dew_point #=> dew point in fahrenheit
138
+ # conditions.dew_point(:c) #=> dew point in celsius
139
+ # conditions.dew_point(:kelvin) #=> anything else raises an exception
140
+ #
141
+ def dew_point(unit = :f)
142
+ text_from_node_with_unit('dewpoint', unit, :f, :c).to_i
143
+ end
144
+
145
+ #
146
+ # The current heat index
147
+ #
148
+ # conditions.heat_index #=> heat index in fahrenheit
149
+ # conditions.heat_index(:c) #=> heat index in celsius
150
+ # conditions.heat_index(:kelvin) #=> anything else raises an exception
151
+ #
152
+ def heat_index(unit = :f)
153
+ text_from_node_with_unit('heat_index', unit, :f, :c).to_i
154
+ end
155
+
156
+ #
157
+ # The current wind chill
158
+ #
159
+ # conditions.wind_chill #=> wind chill in fahrenheit
160
+ # conditions.wind_chill(:c) #=> wind chill in celsius
161
+ # conditions.wind_chill(:kelvin) #=> anything else raises an exception
162
+ #
163
+ def wind_chill(unit = :f)
164
+ text_from_node_with_unit('windchill', unit, :f, :c).to_i
165
+ end
166
+
167
+ #
168
+ # The current visibility in miles
169
+ #
170
+ def visibility
171
+ text_from_node('visibility_mi').to_f
172
+ end
173
+
174
+ private
175
+
176
+ def text_from_node(element_name)
177
+ @doc.xpath("/current_observation/#{element_name}[1]/child::text()").first.to_s
178
+ end
179
+
180
+ def text_from_node_with_unit(element_name, unit, *allowed_units)
181
+ raise ArgumentError, "Unknown unit #{unit.inspect} - allowed units are #{allowed_units.inspect}" unless allowed_units.include?(unit)
182
+ text_from_node("#{element_name}_#{unit}")
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,108 @@
1
+ module Noaaer
2
+ #
3
+ # A Forecast object represents a multi-day forecast for a particular place. The forecast for a given day can
4
+ # be accessed using the [] method; e.g. (assuming +forecast+ is a forecast for 12/20/2008 - 12/24/2008):
5
+ #
6
+ # forecast[1] #=> ForecastDay for 12/21/2008
7
+ # forecast.length #=> 4
8
+ #
9
+ class Forecast
10
+
11
+ class <<self
12
+ private :new
13
+
14
+ def from_xml(doc) #:nodoc:
15
+ new(doc)
16
+ end
17
+ end
18
+
19
+ def initialize(doc) #:noinit:
20
+ @doc = doc
21
+ end
22
+
23
+ #
24
+ # The number of days provided by the forecast
25
+ #
26
+ def length
27
+ @length ||= @doc.find(%q{/dwml/data/time-layout[@summarization='24hourly'][1]/start-valid-time}).length
28
+ end
29
+
30
+ #
31
+ # Get the ForecastDay for day i
32
+ #
33
+ # forecast[1] #=> returns the ForecastDay for the second day
34
+ #
35
+ def [](i)
36
+ forecast_days[i]
37
+ end
38
+
39
+ private
40
+
41
+ def forecast_days
42
+ @forecast_days ||= begin
43
+ days = []
44
+ length.times do |i|
45
+ days << day = NOAA::ForecastDay.new
46
+ day.starts_at = starts[i]
47
+ day.ends_at = ends[i]
48
+ day.high = maxima[i]
49
+ day.low = minima[i]
50
+ day.weather_summary = weather_summaries[i]
51
+ day.weather_type_code = weather_type_codes[i]
52
+ day.image_url = image_urls[i]
53
+ day.daytime_precipitation_probability = precipitation_probabilities[i*2]
54
+ day.evening_precipitation_probability = precipitation_probabilities[i*2+1]
55
+ end
56
+ days
57
+ end
58
+ end
59
+
60
+ def starts
61
+ @starts ||= @doc.find(%q{/dwml/data/time-layout[@summarization='24hourly'][1]/start-valid-time/text()}).map do |node|
62
+ Time.parse(node.to_s)
63
+ end
64
+ end
65
+
66
+ def ends
67
+ @ends ||= @doc.find(%q{/dwml/data/time-layout[@summarization='24hourly'][1]/end-valid-time/text()}).map do |node|
68
+ Time.parse(node.to_s)
69
+ end
70
+ end
71
+
72
+ def maxima
73
+ @maxima ||= @doc.find(%q{/dwml/data/parameters[1]/temperature[@type='maximum'][@units='Fahrenheit'][1]/value/text()}).map do |node|
74
+ node.to_s.to_i
75
+ end
76
+ end
77
+
78
+ def minima
79
+ @minima ||= @doc.find(%q{/dwml/data/parameters[1]/temperature[@type='minimum'][@units='Fahrenheit'][1]/value/text()}).map do |node|
80
+ node.to_s.to_i
81
+ end
82
+ end
83
+
84
+ def weather_summaries
85
+ @weather_summaries ||= @doc.find(%q{/dwml/data/parameters[1]/weather[1]/weather-conditions}).map do |node|
86
+ node['weather-summary'].to_s
87
+ end
88
+ end
89
+
90
+ def image_urls
91
+ @image_urls ||= @doc.find(%q{/dwml/data/parameters[1]/conditions-icon/icon-link/text()}).map do |node|
92
+ node.to_s
93
+ end
94
+ end
95
+
96
+ def weather_type_codes
97
+ @weather_type_codes ||= image_urls.map do |url|
98
+ url.match(/n?([a-z_]+)\d*\.jpg$/)[1].to_sym
99
+ end
100
+ end
101
+
102
+ def precipitation_probabilities
103
+ @precipitation_probabilities ||= @doc.find(%q{/dwml/data/parameters[1]/probability-of-precipitation[1]/value/text()}).map do |node|
104
+ node.to_s.to_i
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,38 @@
1
+ module Noaaer
2
+ #
3
+ # A ForecastDay contains forecast data for a single day. Each day should start at 6am and
4
+ # end at 6am the following day (assuming that is invariant on the part of the NOAA's data
5
+ # feed). ForecastDay objects are accessed using NOAA::Forecast#[]
6
+ class ForecastDay
7
+ # Time when this forecast's valid time span begins
8
+ attr_reader :starts_at
9
+
10
+ # Time when this forecast's valid time span ends
11
+ attr_reader :ends_at
12
+
13
+ # High temperature for the day in Fahrenheit
14
+ attr_reader :high
15
+
16
+ # Low temperature for the day in Fahrenheit
17
+ attr_reader :low
18
+
19
+ # String summary of weather (e.g., 'Fair')
20
+ attr_reader :weather_summary
21
+ alias_method :weather_description, :weather_summary
22
+
23
+ # Symbol representing NOAA weather type. See NOAA::CurrentConditions#weather_type_code
24
+ attr_reader :weather_type_code
25
+
26
+ # URL string for NOAA weather image
27
+ attr_reader :image_url
28
+
29
+ # Percentage probability of precipitation during the day, between 6am and 6pm, as an integer (0-100)
30
+ attr_reader :daytime_precipitation_probability
31
+
32
+ # Percentage probability of precipitation during the evening/night, between 6pm and 6am, as an integer (0-100)
33
+ attr_reader :evening_precipitation_probability
34
+
35
+ attr_writer :starts_at, :ends_at, :high, :low, :weather_summary, :weather_type_code, :image_url, #:nodoc:
36
+ :daytime_precipitation_probability, :evening_precipitation_probability #:nodoc:
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ # require 'libxml'
2
+
3
+ module Noaaer
4
+ class HttpService #:nodoc:
5
+ def initialize(http = Net::HTTP)
6
+ @HTTP = http
7
+ end
8
+
9
+ def get_current_conditions(station_id)
10
+ @HTTP.get(URI.parse("http://www.weather.gov/xml/current_obs/#{station_id}.xml"))
11
+ end
12
+
13
+ def get_forecast(num_days, lat, lng)
14
+ @HTTP.get(URI.parse("http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?lat=#{lat}&lon=#{lng}&format=24+hourly&numDays=#{num_days}"))
15
+ end
16
+
17
+ def get_station_list
18
+ @HTTP.get(URI.parse("http://www.weather.gov/xml/current_obs/index.xml"))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,111 @@
1
+ module Noaaer
2
+ #
3
+ # Data about an NOAA observation station. When accessing current conditions, the NOAA XML API
4
+ # takes a station ID as input; thus, to find the current conditions for an arbitrary location, one
5
+ # must first determine the closest weather station to that location. The NOAA.current_conditions
6
+ # method performs this task implicitly; however, for applications that need to find conditions
7
+ # for the same location(s) repeatedly, it is far more efficient to find the closest weather station
8
+ # once, store that information, and then query directly against the weather station when updated
9
+ # conditions are needed.
10
+ #
11
+ # Station data is stored in a YAML file that is created using the <tt>noaa-update-stations</tt> executable.
12
+ # Be sure to run this command at least once when you first install the NOAA library, and any time
13
+ # thereafter that you would like to get the latest list of stations. I don't imagine the list
14
+ # changes very often but I don't really have any idea.
15
+ #
16
+ class Station
17
+ class <<self
18
+ attr_writer :stations_file #:nodoc:
19
+
20
+ #
21
+ # Retrieve information about a station given a station ID
22
+ #
23
+ # NOAA::Station.find('KNYC') #=> NOAA::Station object for the Central Park station
24
+ def find(id)
25
+ stations.find { |station| station.id == id }
26
+ end
27
+
28
+ #
29
+ # Find the station closest to a given location. Can accept arguments in any of the following
30
+ # three forms (all are equivalent):
31
+ #
32
+ # NOAA::Station.closest_to(37.989, -77.507)
33
+ # NOAA::Station.closest_to([37.989, -77.507])
34
+ # NOAA::Station.closest_to(GeoKit::LatLng.new(37.989, -77.507))
35
+ def closest_to(*args)
36
+ if args.length == 1
37
+ if args.first.respond_to?(:distance_to)
38
+ closest_to_coordinates(args.first)
39
+ elsif %w(first last).all? { |m| args.first.respond_to?(m) }
40
+ closest_to_lat_lng(args.first)
41
+ else
42
+ raise ArgumentError, "expected two-element Array or GeoKit::LatLng"
43
+ end
44
+ elsif args.length == 2
45
+ closest_to_lat_lng(args)
46
+ else
47
+ raise ArgumentError, "closest_to() will accept one Array argument, one GeoKit::LatLng argument, or two FixNum arguments"
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def closest_to_lat_lng(pair)
54
+ closest_to_coordinates(GeoKit::LatLng.new(pair.first, pair.last))
55
+ end
56
+
57
+ def closest_to_coordinates(coordinates)
58
+ stations.map do |station|
59
+ [coordinates.distance_to(station.coordinates), station]
60
+ end.min do |p1, p2|
61
+ p1.first <=> p2.first # compare distance
62
+ end[1]
63
+ end
64
+
65
+ def stations
66
+ File.open(stations_file) do |file|
67
+ yaml = YAML.load(file) || raise("Can't parse #{file.path} - be sure to run noaa-update-stations")
68
+ yaml.map { |station_hash| new(station_hash) }
69
+ end
70
+ end
71
+
72
+ def stations_file
73
+ @stations_file ||= File.join(File.dirname(__FILE__), '..', '..', 'data', 'stations.yml')
74
+ end
75
+ end
76
+
77
+ # GeoKit::LatLng containing the station's coordinates
78
+ attr_reader :coordinates
79
+
80
+ # Station ID (e.g., "KNYC")
81
+ attr_reader :id
82
+
83
+ # Station name (e.g., "New York City, Central Park")
84
+ attr_reader :name
85
+
86
+ # Two-digit abbreviation for state in which station resides (e.g., "NY")
87
+ attr_reader :state
88
+
89
+ attr_reader :xml_url #:nodoc:
90
+
91
+ def initialize(properties)
92
+ @id, @name, @state, @xml_url = %w(id name state xml_url).map do |p|
93
+ properties[p]
94
+ end
95
+ @coordinates = GeoKit::LatLng.new(properties['latitude'], properties['longitude'])
96
+ end
97
+
98
+ # Latitude of station
99
+ def latitude
100
+ @coordinates.lat
101
+ end
102
+ alias_method :lat, :latitude
103
+
104
+ # Longitude of station
105
+ def longitude
106
+ @coordinates.lng
107
+ end
108
+ alias_method :lng, :longitude
109
+ alias_method :lon, :longitude
110
+ end
111
+ end
@@ -0,0 +1,26 @@
1
+ module Noaeer
2
+ class StationWriter
3
+ def initialize(doc)
4
+ @doc = doc
5
+ end
6
+
7
+ def write(io)
8
+ YAML.dump(@doc.find('/wx_station_index/station').map { |node| node_to_hash(node) }, io)
9
+ end
10
+
11
+ private
12
+
13
+ def node_to_hash(node)
14
+ { 'latitude' => node_value(node, 'latitude').to_f,
15
+ 'longitude' => node_value(node, 'longitude').to_f,
16
+ 'id' => node_value(node, 'station_id'),
17
+ 'name' => node_value(node, 'station_name'),
18
+ 'state' => node_value(node, 'state'),
19
+ 'xml_url' => node_value(node, 'xml_url') }
20
+ end
21
+
22
+ def node_value(node, element)
23
+ node.find("./#{element}/text()").first.to_s
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Noaaer
2
+ VERSION = "0.0.4"
3
+ end
data/lib/noaaer.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'time'
2
+ require 'nokogiri'
3
+ require 'geokit'
4
+
5
+ %w(current_conditions forecast forecast_day http_service station station_writer).each { |file| require File.join(File.dirname(__FILE__), 'noaaer', file) }
6
+
7
+ #
8
+ # The NOAA singleton provides methods to conveniently access information from the NOAA weather feed.
9
+ # For the most part, NOAA.current_conditions and NOAA.forecast will be the only entry point into the
10
+ # NOAA API you will need; one exception is discussed below.
11
+ #
12
+ module Noaaer
13
+ autoload :VERSION, File.join(File.dirname(__FILE__), 'noaaer', 'version')
14
+
15
+ class << self
16
+ #
17
+ # Retrieve the current weather conditions for a given latitude and longitude. Returns an
18
+ # instance of NOAA::CurrentConditions.
19
+ #
20
+ # NOAA.current_conditions(37.989, -77.507) #=> NOAA::CurrentConditions encapsulating current conditions at this point
21
+ #
22
+ # <b>Note:</b> This method parses the stored list of all weather stations in the US and then finds the closest one to
23
+ # the given coordinates, as the NOAA XML API only takes a weather station ID as input. Clearly, this is an expensive
24
+ # operation; if your application needs to repeatedly request conditions for the same point, you will be much better off
25
+ # determining the current station once using NOAA::Station.closest_to, storing the station ID, and then passing it into
26
+ # NOAA.current_conditions_at_station when you need to get the latest conditions.
27
+ #
28
+ def current_conditions(lat, lng)
29
+ current_conditions_at_station(Station.closest_to(lat, lng).id)
30
+ end
31
+
32
+ #
33
+ # Retrieve the current weather conditions for a given weather station ID. Returns an
34
+ # instance of NOAA::CurrentConditions.
35
+ #
36
+ # NOAA.current_conditions_at_station('KNYC') #=> NOAA::CurrentConditions encapsulating current conditions in Central Park
37
+ #
38
+ # See discussion above regarding why this method is often preferable to simply calling #current_conditions.
39
+ #
40
+ def current_conditions_at_station(station_id)
41
+ CurrentConditions.from_xml(HttpService.new.get_current_conditions(station_id))
42
+ end
43
+
44
+ #
45
+ # Retrieve daily forecast information for a given latitude and longitude. Returns
46
+ # an instance of NOAA::Forecast.
47
+ #
48
+ # NOAA.forecast(4, 37.989, -77.507) #=> NOAA::Forecast containing next four days of forecast data for given coordinates
49
+ #
50
+ # <b>Note:</b> The NOAA updates this data no more than once an hour, and asks that users of the API not request the forecast
51
+ # for a given location more frequently than that. For more information, please see http://www.nws.noaa.gov/xml/#frequency
52
+ #
53
+ def forecast(num_days, lat, lng)
54
+ Forecast.from_xml(HttpService.new.get_forecast(num_days, lat, lng))
55
+ end
56
+ end
57
+ end
data/noaaer.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "noaaer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "noaaer"
7
+ s.version = Noaaer::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Cody Swann, Gunner Technology"]
10
+ s.email = ["developers@gunnertech.com"]
11
+ s.homepage = "http://gunnertech.com"
12
+ s.summary = %q{Wrapper for NOAA Weather Service API}
13
+ s.description = %q{This gem will help you utilize the NOAA API for weather data}
14
+
15
+ s.rubyforge_project = "noaaer"
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: noaaer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.4
6
+ platform: ruby
7
+ authors:
8
+ - Cody Swann, Gunner Technology
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-14 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: This gem will help you utilize the NOAA API for weather data
18
+ email:
19
+ - developers@gunnertech.com
20
+ executables:
21
+ - noaa-update-stations
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - .gitignore
28
+ - Gemfile
29
+ - Rakefile
30
+ - bin/noaa-update-stations
31
+ - lib/noaaer.rb
32
+ - lib/noaaer/current_conditions.rb
33
+ - lib/noaaer/forecast.rb
34
+ - lib/noaaer/forecast_day.rb
35
+ - lib/noaaer/http_service.rb
36
+ - lib/noaaer/station.rb
37
+ - lib/noaaer/station_writer.rb
38
+ - lib/noaaer/version.rb
39
+ - noaaer.gemspec
40
+ has_rdoc: true
41
+ homepage: http://gunnertech.com
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project: noaaer
64
+ rubygems_version: 1.6.0
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Wrapper for NOAA Weather Service API
68
+ test_files: []
69
+