August 15, 2003

Amazon ウィッシュリストプラグイン - 日本語で悩み中

[ Movable Type , Perl ]

もう一本は Amazon のウェブサービス を使って、Amazon.co.jp からウィッシュリストを引っ張ってきて表示するプラグインを書いてみました。まだ必要最低限のパラメータしか引っ張れないし、日本語の処理も不十分で化ける時がありますが一応動きはします。

CPAN には Net::Amazon という便利なモジュールが登録されていて、これを使えば Web サービスであることをほとんど意識せずに Amazon ウェブサービスを利用するコードが書けます。

package MT::Plugin::AmazonWishlist;
 
use strict;
use warnings;
use Jcode;
use Net::Amazon;
use Net::Amazon::Request::Wishlist; 
use MT::Template::Context;
 
MT::Template::Context->add_container_tag( AmazonWishlist => \&_amazonWishlist );
MT::Template::Context->add_tag( AWProductName => \&_awProductName );
MT::Template::Context->add_tag( AWImageUrl    => \&_awImageUrl );
MT::Template::Context->add_tag( AWUrl         => \&_awUrl );
MT::Template::Context->add_tag( AWOurPrice    => \&_awOurPrice );
 
sub _amazonWishlist {
    my ($ctx, $args) = @_;
    my $res = '';
 
    my $builder = $ctx->stash('builder');
    my $tokens  = $ctx->stash('tokens');
 
    my $ua = Net::Amazon->new(
                              token => $args->{token},
                              locale => $args->{locale}
                              );
 
    my $req = Net::Amazon::Request::Wishlist->new( id => $args->{id} );
    my $response = $ua->request($req);
 
    if ($response->is_success()) {
        for my $property ($response->properties) {
            $ctx->stash('property', $property);
 
            defined (my $out = $builder->build($ctx, $tokens)) or return $ctx->error($ctx->errstr);
     
            $res .= $out;
        }
    } else {
        return $ctx->error( $response->message() );
    }
 
    $res;
}
 
sub _awProductName {
    my ($ctx, $args) = @_;
 
    my $property = $ctx->stash('property')
         or return $ctx->error("Tag called without an amazon wishlist in context");
    
    # Jcode->new($property->ProductName)->euc;
    $property->ProductName;
}
 
sub _awImageUrl {
    my ($ctx, $args) = @_;
    my $size = $args->{size};
    my $img_url = "";
 
    my $property = $ctx->stash('property')
	or return $ctx->error("Tag called without an amazon wishlist in context");
 
    if ($size eq 'small') {
	$img_url = $property->ImageUrlSmall;
    } elsif ($size eq 'large') {
	$img_url = $property->ImageUrlLarge;
    } else {
	$img_url = $property->ImageUrlMedium;
    }
 
    $img_url;
}
 
sub _awUrl {
    my ($ctx, $args) = @_;
 
    my $property = $ctx->stash('property')
	or return $ctx->error("Tag called without an amazonwishlist in context");
    
    $property->url;
}
 
sub _awOurPrice {
    my ($ctx, $args) = @_;
 
    my $property = $ctx->stash('property')
	or return $ctx->error("Tag called without an amazonwishlist in context");
 
    $property->OurPrice;
}

1;

こんなプラグインを書いておいて、

<div class="sidetitle">
Amazon ウィッシュリスト
</div>
 
<div class="side">
  <MTAmazonWishlist token="..." locale="jp" id="...">
    <div class="awitem">
      <a href="<$MTAWUrl$>"><$MTAWProductName$><br/>
        <img src="<$MTAWImageUrl size="small"$>"/>
      </a>
    </div>
  </MTAmazonWishlist>
</div>

というタグをテンプレートに埋め込みます。MTAmazonWishlist タグの属性 token は Amazon ウェブサービスのデベロッパートークン。Amazon のサイトから無料で取得できます。id はウィッシュリストの ID です。URL などに含まれているものを使います。locale を jp にしておけば Amazon.co.jp からデータを引っ張れます。

とりあえず実験目的で作ったものなので、名前、画像、画像のURL、商品のURLしか取得できません。他のパラメータも同じ要領で取得できるので、追加するのは簡単ですがいかんせん日本語が化けまくりではまってしまいました。

日本語が化けるケースは色々あって混乱してしまってよくわからない状況になっちゃってます。Net::Amazon は内部で XML::Parser を用いていることもあってか、応答は UTF-8 で返却されます。この状況で、

  • MT を UTF-8、プラグインでは何もしない → プラグインの部分以外が全部化ける
  • MT を UTF-8、プラグインで Jcode により明示的に UTF-8 に変換 → 同上
  • MT を EUC、プラグインで EUC に変換 → MT::FileMgr::Local.pm がエラー
  • Perl 5.6.0 → Perl 5.8.0 に上げてみた... UTF-8 → EUC 変換ができなくなった。(;´Д`)

うーん、Jcode.pm の UTF-8 絡みはもうお手上げです。

ちなみに MT Plugin Directory にある MTAmazon も同じく Amazon ウェブサービスを利用するためのプラグインで、かなり汎用的なつくりになってるみたいです。

Posted by naoya at August 15, 2003 03:49 AM | トラックバック (5)  b_entry.gif
トラックバック [5件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/349
mt-isbn.plテスト中
Excerpt: 画像を出そうと思って、NET::Amazonを利用してたら、EUCで構築しているため、激しく文字化けしてしまった。いろいろ探していたら、こんなを見つけた。 Amazon ウィッシュリストプラグイン - 日本語で悩み中 この人は、できる人みたいだね。...
Weblog: くものす
Tracked: May 20, 2004 05:53 PM
MTISBN
Excerpt: http://www.asmate.net/software/perl/mt-isbn/ http://siteas.net/usemod10/wiki.pl?DownLoads MTISBNをいれてみました。 するとこんなかんぢに表示されます。 ISBN: 4048970410 やっと文字化けするBugが取れた……UTF-8の問題でした。UTF8のフラグの問題で、フラグ付きU...
Weblog: Bstyle = LOlita + Goth
Tracked: June 10, 2004 12:58 AM
MTISBN
Excerpt: http://www.asmate.net/software/perl/mt-isbn/ http://siteas.net/usemod10/wiki.pl?DownLoads MTISBNをいれてみました。 するとこんなかんぢに表示されます。 ISBN: 4048970410 やっと文字化けするBugが取れた……UTF-8の問題でした。UTF8のフラグの問題で、フラグ付きU...
Weblog: Bstyle = LOlita + Goth
Tracked: June 10, 2004 12:59 AM
Net::Amazon & XML::RSS で Amazon ウィッシュリストをRSSにする
Excerpt: 読みたい本、読まなければならない本は増える一方なのですが消費量は低下するばかりで、Amazonのウィッシュリストはどんどん増えていくのでした。これをWebで確認...
Weblog: Monologue
Tracked: December 23, 2004 10:54 PM
Takara Gakudo Pages
Excerpt: http://www.wikiroom.com/?Tips%2F%BD%F1%C9%BE%A5%B5%A5%A4%A5%C8%A4%F2%BA%EE%A4%EB...
Weblog: PukiWiki/TrackBack 0.1
Tracked: February 3, 2005 01:13 PM
コメント [6件]

Jcode.pmではなく Encode.pm を使うのがイマドキみたいですよ。(see. perldoc Encode)
Jcode と同じく Dan Kogai さんがメンテナです。
# 実際に触ってないので本当のところは知りませんが

[1] Posted by: kawachi1 at August 15, 2003 08:14 AM [返信]

http://naoya.dyndns.org/~naoya/mt/archives/amazon_wl.pl

Perl 5.8.0 で Encode.pm で UTF-8 → EUC-JP 変換させると文字化けは回避できました。

ただ、Encode.pm って Perl 5.6.0 じゃ使えないですよね。自分専用プラグインとして終わりそうな気配。(笑)

[2] Posted by: naoya at August 15, 2003 08:34 PM [返信]

こんばんは。自分でAmazonのウェブサービスを使い始めて、いろいろ調べているうちにたどり着きました。
ウィッシュリストもNet::Amazonも初めて知りました。時間あるときに一通り読みふけりたいと思います。

[3] Posted by: swd at September 14, 2003 07:34 PM [返信]

どうもです。

Net::Amazon は結構便利ですよ。ソースを見ていただいてもお分かりかと思いますや、SOAP や XML なんかは完全に抽象化してくれていますから。

Net::Google なんかもおすすめです。;)

[4] Posted by: naoya at September 16, 2003 01:14 AM [返信]

自力でSOAP::Lite使ってAmazon WebServiceを呼ぶコードを書いたのは勉強になって良かったのですが、これからは素直にNet::Amazonを使います(笑)。本当はRubyで攻めたいのですが、tsundoku.infoをホストしているサーバにはRubyが動かないので何をやるにもPerlです。(普段使わないので良い訓練になります)
Googleもライセンスキーは取得してあります。何かネタを思いついたらNet::Googleで遊んでみます。

[5] Posted by: swd at September 17, 2003 03:07 AM [返信]

Net::Amazon は中で SOAP::Lite を使っているのですが、SOAP::Lite が更に XML::Parser を使っていて、Amazon.co.jp からのレスポンスで日本語が含まれている場合に、たまーに parse error になってしまうのがたまにキズです。

parse 前にちょっと処理を挟んでやって機種依存文字とかその辺を解決してやるといいような気がしてます。

[6] Posted by: naoya at September 18, 2003 12:23 AM [返信]