# Wraps NOAA National Weather Service information
class CurrentConditions
+ @@bot = Irc::Utils.bot
def initialize(station)
@station = station
- @url = "http://www.nws.noaa.gov/data/current_obs/#{@station.upcase}.xml"
- @etag = String.new
- @mtime = Time.mktime(0)
+ @url = "http://www.nws.noaa.gov/data/current_obs/#{URI.encode @station.upcase}.xml"
@current_conditions = String.new
- @iscached = false
end
def update
- begin
- open(@url,"If-Modified-Since" => @mtime.rfc2822) do |feed|
- # open(@url,"If-None-Match"=>@etag) do |feed|
- @etag = feed.meta['etag']
- @mtime = feed.last_modified
- cc_doc = (REXML::Document.new feed).root
- @iscached = false
- @current_conditions = parse(cc_doc)
- end
- rescue OpenURI::HTTPError => e
- case e
- when /304/
- @iscached = true
- when /404/
- raise "Data for #{@station} not found"
- else
- raise "Error retrieving data: #{e}"
- end
+ begin
+ resp = @@bot.httputil.get_response(@url)
+ case resp
+ when Net::HTTPSuccess
+ cc_doc = (REXML::Document.new resp.body).root
+ @current_conditions = parse(cc_doc)
+ else
+ raise Net::HTTPError.new(_("couldn't get data for %{station} (%{message})") % {
+ :station => @station, :message => resp.message
+ }, resp)
+ end
+ rescue => e
+ if Net::HTTPError === e
+ raise
+ else
+ error e
+ raise "error retrieving data: #{e}"
end
- @current_conditions # +" Cached? "+ ((@iscached) ? "Y" : "N")
+ end
+ @current_conditions
end
def parse(cc_doc)
cc = Hash.new
cc_doc.elements.each do |c|
cc[c.name.to_sym] = c.text
end
- "At #{cc[:observation_time_rfc822]}, the wind was #{cc[:wind_string]} at #{cc[:location]} (#{cc[:station_id]}). The temperature was #{cc[:temperature_string]}#{heat_index_or_wind_chill(cc)}, and the pressure was #{cc[:pressure_string]}. The relative humidity was #{cc[:relative_humidity]}%. Current conditions are #{cc[:weather]} with #{cc[:visibility_mi]}mi visibility."
+ cc[:time] = cc[:observation_time_rfc822]
+ cc[:wind] = cc[:wind_string]
+ cc[:temperature] = cc[:temperature_string]
+ cc[:heatindexorwindchill] = heat_index_or_wind_chill(cc)
+ cc[:pressure] = cc[:pressure_string]
+
+ _("At %{time} the conditions at %{location} (%{station_id}) were %{weather} with a visibility of %{visibility_mi}mi. The wind was %{wind} with %{relative_humidity}%% relative humidity. The temperature was %{temperature}%{heatindexorwindchill}, and the pressure was %{pressure}.") % cc
end
private
def heat_index_or_wind_chill(cc)
hi = cc[:heat_index_string]
wc = cc[:windchill_string]
- if hi != 'NA' then
- " with a heat index of #{hi}"
- elsif wc != 'NA' then
- " with a windchill of #{wc}"
+ if hi and hi != 'NA' then
+ _(" with a heat index of %{hi}") % { :hi => hi }
+ elsif wc and wc != 'NA' then
+ _(" with a windchill of %{wc}") % { :wc => wc }
else
""
end
units = reg[2] rescue nil
end
+ if !service
+ if where.sub!(/^station\s+/,'')
+ service = :nws
+ else
+ service = :wu
+ end
+ end
+
if where.empty?
debug "No weather location found for #{m.sourcenick}"
m.reply "I don't know where you are yet, #{m.sourcenick}. See 'help weather nws' or 'help weather wu' for additional help"
wu_units = String.new
- case (units || @bot.config['weather.units']).to_sym
+ units = @bot.config['weather.units'] unless units
+
+ case units.to_sym
when :english, :metric
wu_units = "_#{units}"
when :both
begin
m.reply met.update
@nws_cache[where] = met
+ rescue Net::HTTPError => e
+ m.reply _("%{error}, will try WU service") % { :error => e.message }
+ wu_weather(m, where)
rescue => e
m.reply e.message
end
end
end
- def wu_station(m, where, units)
+ def wu_station(m, where, units="")
begin
xml = @bot.httputil.get(@wu_station_url % [units, CGI.escape(where)])
case xml
end
end
- def wu_weather(m, where, units)
+ def wu_weather(m, where, units="")
begin
xml = @bot.httputil.get(@wu_url % [units, CGI.escape(where)])
case xml
m.reply "couldn't parse weather data from #{where}"
end
wu_out_special(m, xml)
- when /<a href="\/(?:global\/stations|US\/\w\w)\//
+ when /<a href="\/auto\/mobile[^\/]+\/(?:global\/stations|[A-Z][A-Z])\//
wu_weather_multi(m, xml)
else
debug xml
def wu_weather_multi(m, xml)
# debug xml
- stations = xml.scan(/<td>\s*(?:<a href="([^?"]+\?feature=[^"]+)"\s*[^>]*><img [^>]+><\/a>\s*)?<a href="\/(?:global\/stations|US\/(\w\w))\/([^"]*?)\.html">(.*?)<\/a>\s*:\s*(.*?)<\/td>/m)
+ stations = xml.scan(/<td>\s*(?:<a href="([^?"]+\?feature=[^"]+)"\s*[^>]*><img [^>]+><\/a>\s*)?<a href="\/auto\/mobile[^\/]+\/(?:global\/stations|([A-Z][A-Z]))\/([^"]*?)\.html">(.*?)<\/a>\s*:\s*(.*?)<\/td>/m)
# debug stations
m.reply "multiple stations available, use 'weather station <code>' or 'weather <city, state>' as appropriate, for one of the following (current temp shown):"
stations.map! { |ar|