本日の天気予報を取得するクラス

ちょっと現実逃避に作ってみました。http://www.drk7.jp/weather/ から本日の天気予報のデータを取得してきます。
 *絵文字の部分は適宜変更して下さい。

require 'net/http'

class WeatherInfoDrk7
#
#  http://www.drk7.jp/weather/ の天気予報を取得するクラス
#

  WEATHER_EMOJI = {'晴れ'=>'', 'くもり'=>'', ''=>'', ''=>'' }

  def initiailize
    @xml = ''
  end

  # 取得した XML (テストの為に設定もできる)
  attr_accessor  :xml

  #
  #  本日の天気,天気絵文字,降水確率を戻す
  #
  #  使い方 w, e, r = WeatherInfoDrk7.simple_info(pref_code, "東京地方")
  #
  def self.simple_info(pref_code, area_id)
    weather = self.new
    weather.get_xml(pref_code)
    weather.get_area_info(area_id, Time.new.strftime("%Y/%m/%d"))
  end

  #
  # pref_code の天気予報を取得
  #
  def get_xml(pref_code)
    conn = Net::HTTP.new("www.drk7.jp")
    conn.open_timeout = 3
    conn.read_timeout = 3
    res, = conn.get("/weather/xml/#{pref_code}.xml")
    @xml = res.body
  end

  #
  # area_id で指定したエリアの 天気,天気絵文字,降水確率 を戻す
  #
  def get_area_info(area_id, date)
    return "", "", "" unless (Regexp.new("<area id=\"#{area_id}\">.*<info date=\"#{date}\">(.*?)<\/info>.*<\/area>", Regexp::MULTILINE, 'u') =~ @xml)
    area = $1
    area =~ /<weather>(.*)<\/weather>/mu; weather = $1
    area =~ /<period hour="06-12">(.*)<\/period>/u; rain1 = $1
    area =~ /<period hour="12-18">(.*)<\/period>/u; rain2 = $1

    return weather, emoji_weather(weather), ((rain1.to_i + rain2.to_i) / 2).round
  end

  #
  # weather の中の 晴れ、雨などをその順で絵文字に変換する
  # (Testの為に公開)
  #
  def emoji_weather(weather)
    pos = {}
    WEATHER_EMOJI.each_key {|w|
      p = weather.index(w)
      pos[p] = w  if (p)
    }

    pos.keys.sort.map {|p| WEATHER_EMOJI[pos[p]]}.join('')
  end

end


テストコードもありますが、データは省略したので適宜作って下さい。

require File.dirname(__FILE__) + '/../test_helper'

class WeatherInfoDrk7Test < Test::Unit::TestCase

  def test_emoji
    e = WeatherInfoDrk7.new.emoji_weather("雨のちくもりのち晴れ夜には雪")
    assert_equal "&#58944;&#58943;&#58942;&#58945;", e
  end

  def test_get_area_info
    weather = WeatherInfoDrk7.new
    weather.xml = xml_sample
    w, e, r = weather.get_area_info("東京地方","2007/07/16")
    assert_equal "くもり時々晴れ", w
    assert_equal "&#58943;&#58942;", e
    assert_equal 15, r
  end

  def test_get_xml
    weather = WeatherInfoDrk7.new
    weather.get_xml(13)
    assert weather.xml =~ /東京地方/
  end

  def test_simple_info
    w, e, r = WeatherInfoDrk7.simple_info(13, "東京地方")
    assert w =~ /晴れ|くもり||/u
    assert e =~ /&#58942;|&#58943;|&#58944;|&#58945;/u
    assert r >= 0 && r <= 100
  end

  def xml_sample
   <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<weatherforecast>
<title>weather forecast xml</title>
<link>http://www.drk7.jp/weather/xml/13.xml</link>

 ...

</weatherforecast>
EOF
  end

end