Ruby の REXML と RSS Maker で Amazon で売れてるオライリー本のフィードを簡単に作る

使用したライブラリ

We retire raa.ruby-lang.org という Amazon Web Service を簡単に使えるライブラリも存在するが、単にリストを取得するだけなので今回は見送った。

コード

RSS 2.0 で出力する。RSS::Maker.make(version) で引数にバージョンを入れて指定する。
Description にイメージと著者、出版日、価格を入れている。Author は複数タグあるため、カンマで結合。
同じようなものを仕事で Java で作ったことがあったが、Ruby などの Light Weight 言語の手軽さを知ってしまうと戻れない。
結果: http://feed.tilfin.net/amazon/oreilly-bestseller.xml Add to Google
下記のコードでは、ファイル書き出しをコメントアウトして、CGIとしての動作を有効にさせている。

#!/usr/bin/env ruby
#
#  Amazon O'Relly Sales Ranking
#  Rss feed
#
#################################

require 'open-uri'
require 'rexml/document'
require 'rss/maker'

param = {
 'Service' => 'AWSECommerceService',
 'AWSAccessKeyId' => '☆アクセスキーID☆',
 'AssociateTag' => '☆アソシエイトID☆',
 'Operation' => 'ItemSearch',
 'SearchIndex' => 'Books',
 'ResponseGroup' => 'Medium',
 'Sort' => 'salesrank',
 'Publisher' => 'オライリー'
}

params = param.map do |key, value|
  "#{URI.encode(key)}=#{URI.encode(value)}"
end.join("&")

doc = nil
open('http://webservices.amazon.co.jp/onca/xml?' + params) { |resp|
  doc = REXML::Document.new(resp)
}

rss = RSS::Maker.make("2.0") do |maker|

  maker.channel.title = "O'Reilly ベストセラー (Amazon)"
  maker.channel.description = "O'Reilly の Amazon.co.jp のセールストップ 10 を紹介"
  maker.channel.link = "http://feed.tilfin.net/amazon/orelly-bestseller.xml"

  number = 0
  doc.elements.each("/ItemSearchResponse/Items/Item") do |item|

    itmat = item.elements["ItemAttributes"]

    number += 1
    entry = maker.items.new_item
    entry.title = number.to_s + '.  ' + itmat.elements["Title"].text
    entry.link  = item.elements["DetailPageURL"].text

    desc = nil
    item.elements.each("MediumImage") { |img|
        desc = <<EOS
<img src="#{img.elements["URL"].text}"
 width="#{img.elements["Width"].text}"
 height="#{img.elements["Height"].text}"><br>
EOS
    }
    desc += itmat.elements.each("Author") { |a| a.text }.join(", ") + " (著)"
    desc += "<br>発売日:" + itmat.elements["PublicationDate"].text.gsub(/-/, '/')
    desc += "<br>" + itmat.elements["ListPrice/FormattedPrice"].text
    entry.description = desc
    entry.date = Time.now

  end

end

print "Content-Type:application/rss+xml\r\n\r\n"
print rss

#open("oreilly-bestseller.xml", "w") { |out|
#  out.print rss
#}

IE7だと application/rss だけではフィードだと認識されなかった。