2008/01/31


最近は技術情報ばかり書く機会が多く、このブログにメールから投稿する事はあまりなくなりましたが、もしかすると需要はあるかもしれないので...
blosxomをXMLRC経由でポストするスクリプトBXR(blosxom-xmlrpc.cgi)をWindows Live Writerからポストするとサーバ側でパースに失敗していました。
調べた結果、Windows Live WriterはXMLの先頭にBOMを付けてくれるらしく、XMLRPC::Transport::HTTP::CGIがパースエラーを起こしてました。
とりあえず私の所は応急処置で、User-Agentを見て先頭3バイトを削るワークアラウンドで逃げる事にしました。
またWindows Live WriterはcategoryNameとcategoryIdを正しく区別出来ていないようなので、こちらもUser-Agentを見てcategoryIdのみ処理するよう修正しました。
※Windows用にbinmodeしたほうがいいかもしれない。

これで外部XMLRPCキッカー(sidebar.jp等)を使用したモブログ、ブログエディタ等でポスト出来るようになります。

ダウンロード:
Posted at by




Livedoor Readerの海外版、「FastLadder」が公開されました。
FeedFetcherのユーザエージェントは、LDRとそっくり「Fastladder FeedFetcher/0.01」でした。
さて、弄り倒しますか。

fastladder-20070703

あわせて「フィード購読者数カウンタ for blosxom」も修正しました。
ダウンロード:
Posted at by




XMLRPC(XML Remote Procedure Call)は、HTTPを介してXMLを扱い透過的にサーバ側のメソッドを実行するAPI実装です。

最近のミニブログ界ではJaikuがGoogleに買収されてからJaikuに人が入り始め、賑わってから少し経ちます。ミニブログで代表的なTwitterとJaikuは一見同じミニブログに見えて、APIとしては違うものを採用しています。

TwitterのAPIは基本的にRESTとBasic認証および出力フォーマット指定というAPIを採用しており、クライアントを作成する開発者はURLに対してGET/POST出来るライブラリと、XML/JSON/RSS/ATOMの中から自分の使いたいフォーマットを処理出来るライブラリを選ぶ事が出来ます。
またJaikuのAPIはBasic認証ではなくpersonal_keyと呼ばれるAPIKEYとユーザ名で認証します。取得系はTwitterとそれ程変わりませんが更新系は以前にも書いた通りJSONもしくはXMLRPCに限定されてしまっています。つまりJSONで更新したらJSONのレスポンスが、XMLPRCで更新したらXMLRPCのレスポンスが返されます。JSONが扱いにくい言語を使用する場合にはXMLRPCを強制されてしまう事になります。

さて今日はJaikuのAPIに限った話ではなく、Jaikuを使ってXMLRPCのクライアント実装と、XMLRPCサーバについての話をしたいと思います。
まず送受信されるデータについて。

XMLRPCは、決められたXML構成にメソッド名および構造化可能なパラメータをリクエストとして送信し、同じく構造化可能なレスポンスを受け取るXML送受信APIです。
リクエストフォーマットは以下の様な記述になります。
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
  <methodName>メソッド名</methodName>
  <params>
    <param><value><string>パラメータ1</string></value></param>
    <param><value><string>パラメータ2</string></value></param>
  </params>
</methodCall>
またレスポンスフォーマットは以下の様になります。 <?xml version="1.0" encoding="utf-8"?>
<methodResponse>
  <params>
    <param>
      <value>
        <string>結果</string>
      </value>
    </param>
  </params>
</methodResponse>
リクエストパラメータは「params」というノードを括られており、配列になっているのが分かるかと思います。また値が格納される「value」ノードには「<string>」や「<int>」といった、その値の型が定義されています。
上で書いた通り、リクエストパラメータとレスポンスは構造化出来ますので、例えばレスポンスで構造体を表すならば <?xml version="1.0" encoding="utf-8"?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>メンバ1</name>
            <value><int>157</int></value>
          </member>
          <member>
            <name>メンバ2</name>
            <value><string>Sample</string></value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>
と書く事が出来ます。
詳しくはXMLRPCのオフィシャルサイトで確認出来ます。またオフィシャルサイトではXMLRPCを使った処理系毎の実装一覧XMLRPCが使えるサービス一覧も確認出来ます。

ところで、Windows Live WriterBlogWriteubicast Blogger等といったブログ投稿ツールはXMLRPCを使用してブログ記事を操作しています。それらAPIは以下の様に分類されています。
  • Blogger API: Bloggerが提供してるAPI
  • metaWeblog API: Blogger APIに足らない部分を補足する形で登場したAPI
  • MovableType API: Movable Typeが提供してるAPI
  • LiveJournal API: Bloggerが提供してる独自API
一般的に汎用的なブログ投稿ツールでは上記の内、上3点を標準実装しています。
さてJaikuの場合、XMLRPCのインタフェースは一つしか公開されておらず(2007/11/01時点)、そのスペックは presence.send({
    user => 'your username as string',
    personal_key => 'your personal key as string',
    message => 'message as string',
    optional icon => 'icon number as int',
    optional location => 'location as string',
    optional generated => 'generat flag as boolean'
})
こんなイメージとして表現出来ます。
簡単な物をPerlで書くならば

jaiku.pl
#!/usr/bin/perl
use strict;
use Encode qw(from_to);
use XMLRPC::Lite;
use Data::Dumper;

my ($user,$personal_key,$message,$icon) = @ARGV;
from_to($message, "shiftjis", "utf8") if $^O eq "MSWin32";

print Dumper(XMLRPC::Lite
    ->proxy('http://api.jaiku.com/xmlrpc')
    ->call('presence.send', {
            user => $user,
            personal_key => $personal_key,
            message => $message,
            icon => ($icon || 300),
        })->result);
と書く事が出来ますね。これをコマンドラインから
./jaiku.pl username xxxxxxx 本日は晴天なり ※「xxxxxxx」はpersonal_keyです。APIドキュメントの右下あたりに記述されています。
と実行すればJaikuのステータスが更新されます。例では最終引数に省略可能なアイコン番号を付けていますので ./jaiku.pl username xxxxxxx 曇り 398 と実行すれば
jaiku-icon-cloudy
といった感じにアイコンを付ける事が出来ます。
なお、Jaikuのアイコン番号に対する実際のアイコン対応表を作りました。
JavaScriptをOnにして頂いて、以下のリンクをクリックして下さい。
アイコンリストを表示
さて話をXMLRPCに戻して、Perlでは「XMLRPC::Transport::HTTP」というXMLRPCを透過的にPerlのパッケージおよびサブルーチンとバインドしてくれるモジュールがあり、XMLRPCサーバを簡単に実装する事が出来ます。
例えば数値パラメータ2つ貰い足した結果を返すXMLRPCサーバならば以下の様に実装出来ます。 #!/usr/bin/perl

use strict;
use XMLRPC::Transport::HTTP;

package calc;
sub plus {
    shift if UNIVERSAL::isa( $_[0] => __PACKAGE__ );
    my $lhs = shift;
    my $rhs = shift;
    my $res = $lhs + $rhs;
    return {result=>SOAP::Data->type('int' => $res)};
}

XMLRPC::Transport::HTTP::CGI
    ->dispatch_to('calc')->handle;
モジュール名がpackage「calc」に、メソッド名がサブルーチン「plus」にバインドされている事が分かるかと思います。
これを実行するには #!/usr/bin/perl
use strict;
use warnings;
use Encode qw(from_to);
use XMLRPC::Lite;
use Data::Dumper;

my $url = 'http://example.com/xmlrpc/calc.cgi';
warn Dumper(XMLRPC::Lite
    ->proxy($url)
    ->call('calc.plus', 1, 2)->result);
というクライアント側のコードで実行出来ます。
勿論、XMLRPCを扱うならばクライアント/サーバはPerlでなくても良い訳です。pythonで実装するならば from xmlrpclib import ServerProxy
proxy = ServerProxy("http://example.com/xmlrpc/calc.cgi")
print proxy.calc.plus(1, 2)
という実装になります。
XMLRPCは既に色んな言語で実装されており、それぞれに使い方は異なりますが扱う仕様が決められている為に、移植に戸惑う事はそれ程ないかと思います。
※特にpythonに関してはメソッドバインディングされますので、かなり透過的に扱えます。

例を元にXMLRPCを説明して来ましたがどうでしたでしょうか?
色んな言語でJaikuクライアントを実装してみるのも面白いかもしれませんね。

Posted at by