+
+ def wu_station(m, where, units)
+ begin
+ xml = @bot.httputil.get(@wu_station_url % [units, CGI.escape(where)])
+ case xml
+ when nil
+ m.reply "couldn't retrieve weather information, sorry"
+ return
+ when /Search not found:/
+ m.reply "no such station found (#{where})"
+ return
+ when /<table border.*?>(.*?)<\/table>/m
+ data = $1.dup
+ m.reply wu_weather_filter(data)
+ wu_out_special(m, xml)
+ else
+ debug xml
+ m.reply "something went wrong with the data for #{where}..."
+ end
+ rescue => e
+ m.reply "retrieving info about '#{where}' failed (#{e})"
+ end
+ end
+
+ def wu_weather(m, where, units)
+ begin
+ xml = @bot.httputil.get(@wu_url % [units, CGI.escape(where)])
+ case xml
+ when nil
+ m.reply "couldn't retrieve weather information, sorry"
+ when /City Not Found/
+ m.reply "no such location found (#{where})"
+ when /Current<\/a>/
+ data = ""
+ xml.scan(/<table border.*?>(.*?)<\/table>/m).each do |match|
+ data += wu_weather_filter(match.first)
+ end
+ if data.length > 0
+ m.reply data
+ else
+ m.reply "couldn't parse weather data from #{where}"
+ end
+ wu_out_special(m, xml)
+ when /<a href="\/(?:global\/stations|US\/\w\w)\//
+ wu_weather_multi(m, xml)
+ else
+ debug xml
+ m.reply "something went wrong with the data from #{where}..."
+ end
+ rescue => e
+ m.reply "retrieving info about '#{where}' failed (#{e})"
+ end
+ end
+
+ def wu_clean(stuff)
+ txt = stuff
+ txt.gsub!(/[\n\s]+/,' ')
+ txt.gsub!(/ /, ' ')
+ txt.gsub!(/°/, ' ') # degree sign
+ txt.gsub!(/<\/?b>/,'')
+ txt.gsub!(/<\/?span[^<>]*?>/,'')
+ txt.gsub!(/<img\s*[^<>]*?>/,'')
+ txt.gsub!(/<br\s?\/?>/,'')
+ txt
+ end
+
+ 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)
+ # 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|
+ warning = ar[0]
+ loc = ar[2]
+ state = ar[1]
+ par = ar[3]
+ w = ar[4]
+ if state # US station
+ (warning ? "*" : "") + ("%s, %s (%s): %s" % [loc, state, par, wu_clean(w)])
+ else # non-US station
+ (warning ? "*" : "") + ("station %s (%s): %s" % [loc, par, wu_clean(w)])
+ end
+ }
+ m.reply stations.join("; ")
+ end
+
+ def wu_check_special(xml)
+ specials = []
+ # We only scan the first half to prevent getting the advisories twice
+ xml[0,xml.length/2].scan(%r{<a href="([^"]+\?[^"]*feature=warning#([^"]+))"[^>]*>([^<]+)</a>}) do
+ special = {
+ :url => "http://mobile.wunderground.com"+$1,
+ :type => $2.dup,
+ :special => $3.dup
+ }
+ spec_rx = Regexp.new("<a name=\"#{special[:type]}\">(?:.+?)<td align=\"left\">\\s+(.+?)\\s+</td>\\s+</tr>\\s+</table>", Regexp::MULTILINE)
+ spec_xml = @bot.httputil.get(special[:url])
+ if spec_xml and spec_td = spec_xml.match(spec_rx)
+ special.merge!(:text => spec_td.captures.first.ircify_html)
+ end
+ specials << special
+ end
+ return specials
+ end
+
+ def wu_out_special(m, xml)
+ return unless @bot.config['weather.advisory']
+ specials = wu_check_special(xml)
+ debug specials
+ specials.each do |special|
+ special.merge!(:underline => Underline)
+ if special[:text]
+ m.reply("%{underline}%{special}%{underline}: %{text}" % special)