+ 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_weather_multi(m, xml)
+ # debug xml
+ 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|
+ 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, w.ircify_html])
+ else # non-US station
+ (warning ? "*" : "") + ("station %s (%s): %s" % [loc, par, w.ircify_html])
+ 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)
+ else
+ m.reply("%{underline}%{special}%{underline} @ %{url}" % special)
+ end
+ end
+ end
+
+ def wu_weather_filter(stuff)
+ result = Array.new
+ if stuff.match(/<\/a>\s*Updated:\s*(.*?)\s*Observed at\s*(.*?)\s*<\/td>/)
+ result << ("Weather info for %s (updated on %s)" % [$2.ircify_html, $1.ircify_html])
+ end
+ stuff.scan(/<tr>\s*<td>\s*(.*?)\s*<\/td>\s*<td>\s*(.*?)\s*<\/td>\s*<\/tr>/m) { |k, v|
+ kk = k.riphtml
+ vv = v.riphtml
+ next if vv.empty?
+ next if ["-", "- approx.", "N/A", "N/A approx."].include?(vv)
+ next if kk == "Raw METAR"
+ result << ("%s: %s" % [kk, vv])
+ }
+ return result.join('; ')
+ end
+
+ # TODO allow units choice other than lang, find how the API does it
+ def google_weather(m, where)
+ botlang = @bot.config['core.language'].intern
+ if Language::Lang2Locale.key?(botlang)
+ lang = Language::Lang2Locale[botlang].sub(/.UTF.?8$/,'')
+ else
+ lang = botlang.to_s[0,2]
+ end
+
+ debug "Google weather with language #{lang}"
+ xml = @bot.httputil.get("http://www.google.com/ig/api?hl=#{lang}&weather=#{CGI.escape where}")
+ debug xml
+ weather = REXML::Document.new(xml).root.elements["weather"]
+ begin
+ error = weather.elements["problem_cause"]
+ if error
+ ermsg = error.attributes["data"]
+ ermsg = _("no reason specified") if ermsg.empty?
+ raise ermsg