NHKラジオの現在放送中の番組名を返すスクリプト

番組表API(非公式)があるのでNokogiriで切って出力形式に。
何度も繰り返しアクセスするのはNHK側に迷惑だろうから、一度取ったデータはtabledataディレクトリにYAMLで保存します。
また番組表は当日午前5時〜翌日午前5時となっているので、午前5時を一日の始まりとして処理しています。
ただし、NHK第2は午前1時前(不定)〜午前6時が放送休止なので、強引に「放送休止中」と出力していますw

勉強中のものなので下手くそですがw

参考:
らじる★らじるの番組表API - 別館 子子子子子子(ねこのここねこ)
スクレイピングのためのNokogiri利用メモ - それはそれ。これはこれ。

# coding: utf-8

require 'open-uri'
require 'nokogiri'
require 'yaml/store'

def read_saved_data(save_file_path)
  saved_data = IO::read(save_file_path)
  readed_data = YAML::load(saved_data)
  readed_data['timetable']
end

def get_timetable(url, save_file_path)
  h = {}
  doc = Nokogiri::HTML(open url)
  items = doc.xpath("//item")
  items.each do |item|
    hj = {}
    item.children.each do |j|
      hj[j.name] = j.text.strip
    end
    index = item.xpath("eventid").text.to_i
    h[index] = hj
  end
  
  # save timetable data as YAML
  metadata = YAML::Store.new(save_file_path)
  metadata.transaction do
    metadata["timetable"] = h
  end
  h
end

def check_nowonair(h, now)
  nowonair = {}
  h.each do |index, value|
    if Time.parse(value["starttime"]) <= now && now <= Time.parse(value["endtime"])
      nowonair[:title] = value["title"]
      nowonair[:starttime] = value["starttime"].scan(/\d\d:\d\d/)[0]
      nowonair[:url] = value["text"]
    end
  end
  nowonair
end

ch = ARGV[0].downcase
case ch
when "r1" then ch_sign = "第1"
when "r2" then ch_sign = "第2"
when "fm" then ch_sign = "FM"
else raise ArgumentError, "argument must be r1/r2/fm"
end

tbl = {} 
now = Time.new
broadcast_time = now - 5 * 60 * 60
save_file_path = File.expand_path("tabledata/nhk#{ch}_#{broadcast_time.strftime("%y%m%d")}_timetable.yaml")

url = "http://cgi4.nhk.or.jp/hensei/api/sche-nr.cgi?tz=all&ch=net#{ch}&date=#{now.strftime("%Y-%m-%d").to_s}"

Dir.mkdir(File.expand_path("tabledata")) unless File.directory?(File.expand_path("tabledata"))

if File.exists?(save_file_path)
  tbl = read_saved_data(save_file_path)
else
  tbl = get_timetable(url, save_file_path)
end

nowonair = check_nowonair(tbl, now)
nowonair[:starttime] = "放送休止中" unless nowonair[:starttime]

puts "NHK#{ch_sign} #{nowonair[:starttime]} #{nowonair[:title]} #{nowonair[:url]}"