Showing posts with label Atom. Show all posts
Showing posts with label Atom. Show all posts

Oct 30, 2006

PaginatedFeedのバックストーリー

Ogawa::Buzz: PaginatedFeed公開の背景と意義を説明するのがこのエントリーの目的です。

Movable Typeを含むブログツールを使っているほとんどの人にとって、RSSやAtomとは、再構築時または閲覧時に勝手にレンダリングされる特定のXML形式で書かれた「ファイル」だ、そのファイルをアグリゲートしてブログリーダやブログ検索などのサービスが提供されるのだ、という認識かもしれません。

物理的な実体としてのフィードは確かにそういう認識であってもよいのですが、フィードはブログの「インタフェース」でもあります。それぞれブログには(各Webページのlink要素によって)フィードURLが関連付けられており、フィードURLは、GETリクエストを受け取るとフィード(=機械的に操作可能なブログのメタ情報)をレスポンスとして返す「Web API」になっています。ブログリーダやブログ検索などはそのAPIを介して収集したフィードをサービスの対象にしているわけです。

そう考えると、ただ最新のN件のエントリーを取り出せるだけでは、Web APIとしてはあまりにもしょぼくね?と思えてくるはずです(思えない?そうですか、それでもいいですが私はしょぼいと思います。もっとリッチなAPIを提供してアプリもそうしたAPIに対応するようになった世界の方に夢を感じます。)。

例えば、Google Blogger (beta)のフィードURLは、GData APIのエンドポイントURLになっていて、GETリクエストによって(Paginationを用いて)全エントリーの内容とメタ情報、エントリーのEditURIを取得できるようになっています。もちろんそれだけでなく、フィードURLやエントリーのEditURIに対して更新操作も可能です。

GData APIなみの機能を実現することは当面無理だとしても、全エントリーとメタ情報を取得できるようにすることは難しくありません。そういうわけで、それを実現したのがPaginatedFeedなのです。

Paginationのナビゲーション用にOpenSearch 1.1 Response elementsを含むようにしたことに関しては若干の議論の余地があるかと思います。もしナビゲーション用のlink要素がなければ、「PaginatedFeedに特定の引数とともにGETリクエストすれば所定のエントリー群の情報が得られることを知っているクライアント」でなければ任意のエントリーの情報を取得することはできません。これに対して、OpenSearchのResponse elementsを含めておけば、OpenSearch用のクライアントが共通のインタフェースでフィードを取り扱える、という利点があります。ついでに言うと、これはGData APIのフィードでも採用している方式でもあります。もちろん、alternativeな方法を採ることもできますが、そうする意味もないでしょう。

さて、もう語ることはあまり残っていません。

PaginatedFeedを活用するには、特定の引数とともにGETリクエストすれば所定のエントリー群の情報が得られることを知っているクライアントかOpenSearchクライアントを用意する必要があります。そうでなければ通常のフィードと変わりありません。

ブログ検索用のクローラーがOpenSearchに対応していれば、いずれは全文検索してくれるようになる(かも)、と信じて枕を高くして寝ましょう。

そうそう、これはまったくコンテキストが異なりますが、Movable Typeのmt-search.cgiをOpenSearchに対応させるという話なら、Niall Kennedyがずいぶん前に書いているので、そちらに興味がある方は以下を参考にされるとよいでしょう。

OpenSearch standard using Movable Type

Oct 29, 2006

PaginatedFeed公開

Movable Typeで、Pagination機能付きのRSSやAtomを生成するツールを作ったので公開しておきます。

PaginatedFeed - ogawa - Pagination機能付きのRSSやAtomを生成するMovable Typeアプリケーション。 - Google Code

Movable TypeでAtomフィードやRSSフィードを静的に生成するとき、最新の指定個数のエントリーしか対象にならないのが面白くないとは思いませんか。私には、こうした安直な「部分フィード」はいわば生成コストや取得コストの軽減に特化された形式であって、対象コンテンツセットの「表現」としての性質は必ずしも芳しくないのではないか、と思えてなりません。例えば、部分フィードを元に対象コンテンツ全体を把握することも対象コンテンツの更新内容全体を把握することもできませんし、部分フィードを対象とした検索エンジンはブログ空間を対象とした検索エンジンとはなり得ません。

思い切って全エントリーを含むフィードを生成するというソリューションもあり得ますが、フィードが巨大になるため、再構築を行うWebサーバの負荷、(HTTP Compressionを使ったにせよ)トラフィック、その巨大フィードを利用するクライアントプログラム・サービスの負荷が問題となります。

一方で、OpenSearchのレスポンスフィード(要素)やGoogle Blogger betaのAtomフィードは、openSearchというXML名前空間を使ったフィードのPaginationを実現しています。

これと同じことがMovable Typeでも実現できればよいのではないか、じゃあ作っちゃえ、と思って作ったのがPaginatedFeedです。PaginatedFeedでは、表示したいエントリーのオフセットと件数を指定してフィードを生成できます。また、フィードにOpenSearchレスポンスに必要な要素を追加するのに便利ないくつかのテンプレートタグを実現しています。

興味のある方は上記リンクよりどうぞ。

May 25, 2006

Microsoft Word 2007 beta 2からの投稿テスト

どいつもこいつもマクブクマクブク泡吹いててキニクワネエ、じゃなくて(!)、超重要なMicrosoft Office 2007のbeta 2が公開されたことにあまり言及していない。特にMicrosoft Word 2007 beta 2(Microsoft Office Word 2007 製品情報)には、AtomAPIやXMLRPC(MetaWebLog)で主要なブログシステムへの投稿ができるようになっているのに、試してみたという記事すら目にしないのはどうしたことだ。

…と思ったので、試してみた。

まず、ファイルメニューが見つからない…と思ったらこの左上のアイコンがファイルメニューらしい。ただの飾りかと思った…。というか、このホーム、挿入、ページレイアウトっていうのも従来のコマンドディレクトリ選択式のメニューではなく、Contextual Menuになっているわけだね。これはこれで正しいUIで、編集コンテキストごとに選択できるコマンドが制限されて分かりやすいと言える。

気を取り直して、ファイルメニュー→発行→ブログを選択する。

ここまで辿り着くのが大変なだけで後は難しくない。アカウントの管理ウインドウから他のAtomAPI/XMLRPCクライアントアプリケーションと同様に設定するだけなので設定方法は省略する。後は普通にWord上で文章を編集して「発行」するだけ。Wordが大得意な人にとっては便利かもしれない。生成するHTMLも割ときれいなものだと言えるし。

ちなみにAPIとして「Atom」を選択すると失敗するというか登録できない。bloggerだと問題なくアカウント登録・投稿できるのでMovable Typeの実装の問題だと思われる。「MetaWebLog」を試してみるとすんなりうまく行った、というかこれがそのテスト投稿。

今のところ、添付画像やカテゴリーのハンドリングがよく分からない。Word上で画像を貼り付けてポストするとその部分だけ抜け落ちる(上の画像はMovable Typeの管理画面からアップロードしたもの)。Picture Upload用のURLを設定するオプションもあるのでftpかWebDAVで何とかするのかもしれない。カテゴリーについては設定する方法がない。

May 1, 2006

MapUp: Trackback / Atom-enabled Google Map

Google Maps API v2の練習がてら、MapUpっての作ってみました。

MapUp: Trackback/Atom-enabled Google Map

MapUpは、Google Maps APIを使って実現された、トラックバックを送りつけられる地図です。この地図では指定された地点の近辺に対して送信されたトラックバックを地図上にマーカー表示します。

また、指定された地点の近辺に対して送信されたトラックバックをリストしたAtom Feedを取得することもできるので、このFeed URLをRSS/Atomリーダーなどに登録して定点観測できます。ALPSMAP baseでも同じことができますが、そこは「ありもの」でも割と簡単に実現できるということで。

説明がどうにも分かりにくい!と思いますが、噛み砕いて言うと、

  • 「http://as-is.net/maps/mapup.cgi/coords/緯度,経度」をトラックバックURLに指定してトラックバックPingを送信できるよ。
  • すると、「http://as-is.net/maps/mapup.cgi/coords/緯度,経度?view=html」で表示されるマップに、送信したトラックバックに対応するマーカーが表示されるよ。他の人が近所にトラックバックしたのも一緒に表示されるので情報の共有ができるよ。
  • 「http://as-is.net/maps/mapup.cgi/coords/緯度,経度」というURLをRSS/Atomリーダーに登録しておくと、他の人が近辺にトラックバックしたことが自動的に通知されるので便利だよ。

ってことです。うーん分かりにくいですかね。

で、以下は少しadvancedな説明。

MapUpは緯度、経度のペアで示される「地点」リソース(便宜的にcoordsURLと呼ぶ)、「トラックバックアイテム」リソース(便宜的にitemURLと呼ぶ)に対するREST風のインタフェースを備えています。

coordsURL

coordsURLは以下のような形式を採ります。

http://as-is.net/maps/mapup.cgi/coords/緯度,経度

このcoordsURLに対するGET, POSTリクエストで「地点」リソースに対する操作が行えます。

  • ある地点の近辺に送信されたトラックバックを閲覧するには、coordsURLに対してGETリクエストを行います。戻り値はAtom Feedとして出力されます。
  • また、coordsURLに「?view=html」というオプションを指定すると、このAtom FeedをGoogle Mapsを使って描画して表示します。ブラウザなどで閲覧する場合にはこのURLを指定すればよいということです。例: http://as-is.net/maps/mapup.cgi/coords/35.658586,139.745450?view=html
  • ある地点にトラックバックを送信するには、上記のURLに対してPOSTリクエストを行います。BlogツールのトラックバックURLに上記のフォーマットのURLを指定するだけでよいということです。

itemURL

itemURLは以下のような形式を採ります。

http://as-is.net/maps/mapup.cgi/item/ID

このitemURLに対するGET(取得), POST(更新), DELETE(削除)リクエストなどで「トラックバックアイテム」リソースに対する操作が行えるようになる予定です。今のところろくに実装していません。

2006-05-09追記: 少しはリクエストがあるようなので開発版をsubversionで公開しておきます。

コマンドラインから取得:

$ svn co http://ogawa.googlecode.com/svn/trunk/MapUp MapUp

ブラウザでぶらぶら取得:

http://ogawa.googlecode.com/svn/trunk/MapUp

Apr 12, 2006

Re: Let Readers decide How RSS gets sent

404 Blog Not Found:Let Readers decide How RSS gets sent

別にORの論理に囚われてはいないだろう、と思った。

選択肢を読者の側にもたせることは当然のことである。読者が全文だけではなく要約を、日本語だけではなく英語を望むのならそれを実現したらいい。

ではしかし、極端な話をすると、視覚に障碍を持つ読者に対して、音声データに変換したcontentを持つFeedを配信するだろうか?

…しないだろう。…いやもちろんしてもいいよ、でも手元にしかるべきリーダーがあり、それを用いて音声データに変換した方が認識率の点でもスピードの点でも優れた結果が得られるし、点字ディスプレイもある。また、言語間翻訳についても同様のことが言えそうな気がする。generalなスキーマを用いた機械翻訳の結果をFeedとしてサービスされるよりは、書き手と読み手が共通に持っていると期待されるスキーマを機械翻訳に役立てた方がより良い意思疎通が可能だろうから。

もっとつまんない話をしてみようか。「本文の先頭200文字を切り出したものが『要約』」とする書き手と、「そんなものを『要約』だなんて笑止」という読み手は永遠に折り合えない、と。あるいは、読み手がひらがなのみのFeedやルビ付きのFeed、仮名と常用漢字のみを使ったFeedを求めたら、と。

つまり何が言いたいかと言えば、選択肢を読者の側にもたせることが重要なのは事実だが、それをすべて単体サーバ上で実現あるいは提供でき、かつそれが最良だと信じることには、少なくとも現時点では懐疑的にならざるを得ない、ということだ。もっと悲観的な書き方をすると、実のところ書き手は読者のことをよく理解してはいないし、機械はもっと理解していない(だから集合知なんてものに大それた期待をもってしまう、と蛇足)。

であるならば、次善の策は最もgenericな情報を、as isで、メタ情報として与えることだ。

全文を提供されていれば、その要約を生成することはそう難しくない一方、いい加減な要約から意味のある要約を生成することは困難を極める。原文(日本語文)で提供されていれば、その他言語訳を生成するのは外部サービスやFeed Reader上で既にできるかいずれはできるという期待が持てる一方、低品質な(機械翻訳された)英文訳から高品質な他言語訳を生成することは至難だ。半構造が与えられていれば、音声リーダは効率良く読み上げることができる一方、構造を除去した文章の塊を読み上げるのは甚だ効率が悪い上、あらかじめ失われた構造を再現することもまた困難だ。

だからすべての可能性を否定しないために全文を提供すると言っているのであり、これが現時点での「究極のAND解(つまりはas isで何もしない)」なのだ。残念ながら。


それとは別の話をすると、「選択論理的な何か」がしばしば作用するのは主にFeed Readerソフトウェア/サービスの問題だ。本質的には「URL」がuniqueなのであって、それに対応付けられるFeedがuniqueである必要はない。しかし、多くのソフトウェア/サービスは「FeedのURL」を登録し、その内容を閲覧するようになっている。したがって読者は「FeedのURL」のuniquenessを意識せざるを得ず、それゆえ、「どちらのFeedを読ませるか」「どちらのFeedを読むか」ということがしばしば議論の俎上に上がるのだし、Feed提供者はFeedのURLを軽々に変更することを許されないのだ。

これは明らかにおかしい、登録するのはURLにすべきだ、登録されたURLに対して複数のFeedを読者のpreferenceに従って、「取得して」もしくは「生成して」、表示すべきだというのがひとつの素朴な意見である。「取得する」部分の実装に難しい点は何もない(弾さんが指摘している通り)。

複数のFeedをremixしたFeedを配布する場合のように、remixed FeedのURL自体がそのコンテンツセットの意味を規定していると考えるのが自然なこともある。だから、Feed URLを登録するのが統一的で自然なやり方なのだという意見もあるかもしれない。しかし、そうしたmachine-generatedなFeedは、そのURL自体に関連付けられたFeedだと考えればよいのであって、本質的にFeed URLの所在を意識することを読者に強いることは一切なくなるべきだろう。

Mar 27, 2006

Re^2: MT 3.2のAtom API

というわけで、BlogWriteの作者さまから非常に丁寧な説明をいただきました。ありがとうございます。

HepCat Dev and Test: Re: MT 3.2のAtom API

もろもろ勘案すると、Ogawa::Buzz: MT 3.2のAtom APIに載っけた修正に加えて、以下の修正を行えば、無事BlogWriteからMT 3.2のAtom APIを利用でき、過去記事の取得も正常に行えます。

--- lib/MT/Atom.pm.bak Fri Mar  3 15:18:34 2006
+++ lib/MT/Atom.pm Tue Mar 28 09:17:10 2006
@@ -9,6 +9,7 @@
 
 package MT::Atom::Entry;
 use base qw( XML::Atom::Entry );
+use MT::Util;
 
 sub new_with_entry {
     my $class = shift;
@@ -17,22 +18,15 @@
     $atom->title(MT::I18N::encode_text($entry->title,undef,'utf-8'));
     $atom->summary(MT::I18N::encode_text($entry->excerpt,undef,'utf-8'));
     $atom->content(MT::I18N::encode_text($entry->text,undef,'utf-8'));
-    my $mt_author = MT::Author->load($entry->author_id);
+    $atom->content->type('text/html');
+    my $mt_author = $entry->author;
     my $atom_author = new XML::Atom::Person();
     $atom_author->set('name', MT::I18N::encode_text($mt_author->name(),undef,'utf-8'));
     $atom_author->set('url', $mt_author->url());
     $atom_author->set('email', $mt_author->email());
     $atom->author($atom_author);
-    my @co_list = unpack 'A4A2A2A2A2A2', $entry->created_on;
-    my $co = sprintf "%04d-%02d-%02dT%02d:%02d:%02d", @co_list;
-    my $epoch = Time::Local::timegm($co_list[5], $co_list[4], $co_list[3],
-                                    $co_list[2], $co_list[1]-1, $co_list[0]);
-    my $blog = MT::Blog->load($entry->blog_id);
-    my $so = $blog->server_offset;
-    $so += 1 if (localtime $epoch)[8];
-    $so = sprintf("%s%02d%02d", $so < 0 ? '-' : '+', 
-                  abs(int $so), abs($so - int $so)*60);
-    $co .= $so;
+    my $blog = $entry->blog;
+    my $co = MT::Util::ts2iso($blog, $entry->created_on);
     $atom->issued($co);
     $atom->add_link({ rel => 'alternate', type => 'text/html',
                       href => $entry->permalink });

content要素にtype属性を追加したほか、MT::Util::ts2iso()を使ってRFC3339準拠のタイムスタンプを生成・追加しました。また、無駄なDBアクセスを削減するためにMT::Entryのメソッドblog, authorを用いてみました。


とは言うものの、MT 3.2のサポートするAtom APIはold-fashionedなので、無理に上記のパッチをあててまでBlogWriteからAtom APIを利用する必要はないかもしれません。

日本語のコンテンツがすべてBase64でエンコーディングされている気がします。

に関しては、MTにバンドルされているXML::Atom 0.07ではprintableか否かの判定に失敗してmode="base64"で出力され、最近のバージョン(0.19?)では正しくmode="xml"で出力されるようになっています。

Mar 26, 2006

MT 3.2のAtom API

MT 3.2のAtom APIがうまくないらしいという話を聞きました。

ここギコ!: MovableTypeのAtom APIって動いてます?(誰か助けてください)

ひとまず、Atomサービスの一覧のURLを修正すべく、以下のようにパッチをあててみました。

--- lib/MT/AtomServer.pm.bak Fri Mar  3 15:18:34 2006
+++ lib/MT/AtomServer.pm Sun Mar 26 20:57:15 2006
@@ -31,7 +31,6 @@
         handle => \&handle,
     );
     $app->{default_mode} = 'handle';
-    $app->{is_admin} = 1;
     $app->{warning_trace} = 0;
     $app;
 }

このパッチ自体はこっち(MT_3_2_ja2_UO_Patch - ogawa - Google Code)にコミットしておきました。

BlogWrite自体使ったことがなかったのでよく分かりませんが、Endpointにhttp://www.example.com/mt-atom.cgi/weblogを指定して試してみました。私の試した範囲では、過去ログの取得機能がうまく動かないことを除けば、特に問題なく動いている様子です。

BlogWriteがC:\Program Files\witha\BlogWrite\api以下に出力しているログを見ると、get_postsには成功していることが確認できます。MTが返す結果がBlogWriteの期待する形式と違うのかもしれないなと思っているのですが、このあたりは他のAtomPP対応のサービスと比較してみないとよく分かりませんね。

ひとまず作者さまにトラックバックしておきます。

HepCat Dev and Test: BlogWrite 2.4.1.1公開

ところで、is_adminというフラグは、MTのアプリケーションURLを決定する際に、CGIPath、AdminCGIPathのどちらをベースURLとして利用するか判断する目的で用意されているものです。というかそう考えられます。CGIPathではhttpを、AdminCGIPathではhttpsをベースURLに指定したり、後者のPathにはBasic認証を施したりするのはreasonableでしょう。

AdminScript(mt.cgi)は後者であるべきなのは明らかですが、AtomScript(mt-atom.cgi)はどちらか判断が付きかねます。XMLRPCScript(mt-xmlrpc.cgi)は前者なのでAtomScriptも前者でよいというのが一つの考え方で、上記のパッチはそれに従ったものです。一方で、AtomScriptはAdminScriptと同様にMT CMSへのログインや制御を行うのでAdminScriptと同程度にsecureでなければならないというのがもう一つの考え方です。

だったら、$app->{is_admin}=1の状態で、$app->uri()を呼び出したらAdminCGIPathを使ったアプリケーションURLを生成して欲しいわけですが、実際にはAdminCGIPathを使ったAdminScriptのURLしか返しません。この点を修正したければ以下のようにするとよいでしょう。

--- lib/MT/App.pm.bak Fri Mar  3 15:18:34 2006
+++ lib/MT/App.pm Mon Mar 27 11:31:22 2006
@@ -1005,11 +1005,11 @@
 
 sub uri {
     my $app = shift;
-    $app->{is_admin} ? $app->mt_uri(@_) : $app->app_uri(@_);
+    $app->app_uri(@_);
 }
 sub app_uri {
     my $app = shift;
-    $app->app_path . $app->script . $app->uri_params(@_);
+    ($app->{is_admin} ? $app->mt_path : $app->app_path) . $app->script . $app->uri_params(@_);
 }
         # app_uri refers to the active app script
 sub mt_uri {

ただし、もし仮に「$app->{is_admin}=1の状態で、$app->uri()を呼び出したらAdminCGIPathを使ったAdminScriptのURLを返す」仕様に依存したアプリケーション・プラグインがあったとしたら正常に動作しないことになります。このため、MT_3_2_ja2_UO_Patch - ogawa - Google Codeでは、lib/MT/AtomServer.pmのis_admin属性を落とすという修正方法を採っています。

Dec 9, 2005

FeedBurner の Item Stats をオフした件について。

FeedBurner(RSSやAtomなどのXMLフィードを中継配信してくれるサービス)を300日ほど使用し続けています。私の借りているサーバーの代わりに各種形式でXMLフィードを配信してくれるのに加えて、ブラウザヴィジブルにしてくれたり、統計を取ってくれたりと重宝しています。

Ogawa::Buzz: FeedBurnerに移行した件について。

この手のフィードの中継・変換サービスで重要になるのは機能だけでなく、中継配信の信頼性や、もし何らかのマニピュレーションをフィードに対して施すのであれば、その操作の透明性も重要です。Web上のサービスである以上「信頼性」に関しては「それなり」のものでしかあり得ませんし、「操作の透明性」に関しては仕様が明文化されているとは言い難くやや不満が残ります。

さて、Item StatsはFeedBurnerの機能の一つでフィードに含まれるitemのクリック数をトラックすることでitemごとの利用統計を与えるサービスです。クリック数をトラックするために、FeedBurnerはitemのlink要素を「http://feeds.feedburner.com/ogawa?m=18」などに書き換え、このURLへのアクセスは元のlink要素のURLへリダイレクトされるようになっています。

FeedBurnerのフィードをブラウザ経由で利用する場合にはこれで問題ないのですが、そのフィードを操作するソフトウェアでは問題が起き得ます。例えば、naoyaのはてなダイアリー - はてなブックマークの概要取得の処理の、

  1. 該当エントリーに Feed Auto-Discovery を実行する
  2. その中で最初に見つかった Feed (link タグで一番上にあるもの) を GET する
  3. Feed を parse して、ブックマークされた URI を link 要素にもつ要素を探す
  4. その要素に content 部分 (RSS 1.0 なら content:encoded、Atom なら content) があればそれを取得、なければ description を取得

という処理を考えてみると、link要素がリダイレクトURLに書き換えられているFeedBurnerフィードでは、このロジックが機能しません(だから中途半端な概要がはてなブックマークに引用されてしまう)。bulkfeeds.netやlivedoorブログ検索などがうまくインデックスしてくれないのも似たような事情なのではないかと疑っています。link要素のURLを全部HEADしてから比較してもらえばよいのかもしれませんが、すべてのサービス・アプリで対応することを期待するのは馬鹿げています。

また、無料アカウントでもItem Statsが使えるのに、PROアカウントでないとAwareness API経由でItem Stats情報を取得できません(GetItemStatできません)。この非対称性には正直苛っとさせられますね。

さらに、他の人のブログで引用されるときにリダイレクトURLをReferされたり、リダイレクトURLをブックマークされたりしても、Item Statsのページ以外の方法では観測できません。というより、Item Statsのページは各アイテムのクリック数しか表示しませんから、実際には観測不可能だということになります。前述のようにAPI経由で利用するためには有料アカウントが必要で、APIで取得できる情報は(Item Statsのページ同様)やはりサマリー情報だけに縮約されます。要は、ユーたちの大事なREFER(R)ER情報がFeedBurnerに掠め取られているんだゼ、ということです。

ではどうすればよいのかというと、実はItem Statsの機能をdisableするとFeedBurnerはlink要素を書き換えないので、disableすればすべてが解決します。デメリットはItem Statsが使えなくなるというただ一点です。私は問答無用でdisableしました。

方法はいたって簡単。(1) 各フィードのAnalyze画面で「StandardStats」を選び、(2) 「Feed item link clicks」のチェックボックスを外し、(3) 「Save」するだけです。

この件でお悩みの方はお試しあれ。

2005-12-12追記:

この設定を行うと既存のリダイレクトURLはすべて無効になり、「http://feeds.feedburner.com/ogawa?m=18」はそのフィードURL自体を指すようになるようです。つまり、すでに誰かがリダイレクトURLをブックマークしている場合には到達不可能になってしまいます。これはまあデメリットですね。

フィードURLとItem IDから実URLをresolveするAPIを提供してくれてもいいのだが>FeedBurner

Feb 22, 2005

FeedBurnerに移行した件について。

Movable Typeの再構築が遅いの速いのという話がありますが、よくよく考えるまでもなくメイン・インデックスが再構築される(エントリー投稿・更新、コメント、トラックバック)時、RSS 1.0, 2.0, Atomの3つのXML Feedも一緒に再構築されています。ASP型のサービスでは大抵いずれか一つしか提供していないのにMovable Typeの親切ぶりはどうよ、どうなのよ、ねえ、と思わなくもありません。

個人的には一つだけにして当社比3倍(実際には他のアーカイブも再構築されるのでそんなに速くなりません)と行きたいところですが、Bloglinesで他のフィードにもまんべんなく読者が付いていることから判断するに、適当な方法で他のFeedのユーザーを誘導してやる必要が明白にあるということです。

とりあえずindex.rdf, index.xmlからatom.xmlにリダイレクトしてみたのですが、Bloglinesが3回ずつアビっていかれるご様子。また、AtomとRSSが将来統合されたらAtomという名前ですらなくなったりする気もしてその時またatom.xmlから変更するのかよ、と。将来Jabber/XMPP Botがフィード更新の通知を受け取ってから即時GETに来るようなフレームワークが一般的になったときに、今よりFeed Provider側(つまりは私の使っているサーバ)にトラフィックが集中しそうじゃんか、と。更新通知する仕組みを皆が用意するのは結局現実的でなくて適当なアウトソース先に丸投げしてそこが勝手に「アドバンストなテクノロジー」を発揮してくれればいいじゃんか、と。要するにもう少しユニバーサルで賢いやり方はないかと思ったわけです。

そこでFeedBurnerタン(FeedBurner - Point your feed here. We'll do the rest.)の登場ですよ。

FeedBurnerについてはGoogle 検索: FeedBurner。おいらの代わりにXML Feedの配信してくれるのに加えて、ブラウザヴィジブルにしてくれたり、統計を取ってくれたり、他のFeedをマージしてくれたりと(簡単にできることは)色々してくれます。多分「アドバンストなテクノロジー」も勝手に導入してくれるでしょう。

私のやった作業はこんな感じです。

当初Atom Feedを生成して、それをFeedBurnerに配信させる方法を記述していましたが、それだとbulkfeedsを含め多数のアプリケーションで正常に読み込めない問題があるようです。以下はRSS 2.0 Feedを生成するものとして記述を修正してあります。
  1. RSS 2.0 Feedを昔の名前(index.xml)以外の名前で生成するようにします。
  2. FeedBurnerでアカウントを作って1.で生成したFeedを指すようにします。これで「http://feeds.feedburner.com/AS-U-LIKE」という名前で配信できるようになりました。
  3. テンプレートで昔のFeedを参照している部分を2.で作ったものに書き換えます。私の場合例えばヘッダは以下のように書き換えてあります。
    <link rel="alternate" type="application/rss+xml" title="RSS"
          href="http://feeds.feedburner.com/ogawa" />
    <link rel="alternate" type="application/atom+xml" title="Atom"
          href="http://feeds.feedburner.com/ogawa" />
    
    なぜAtom形式でも宣言しておくかというと、RSS形式からAtom形式への変換はFeedBurnerが自動的にやってくれるからです。前者だけでも構わないと思います。
  4. 「移転しました」Feedを作っておきます。
  5. 適当な期間放置して、4.の「移転しました」Feedを削除します。
  6. やっぱり4.,5.は良くないっぽい(Bloglinesのsubscribe情報が全部消えた)。代わりに旧Feedから新Feedへpermanentなリダイレクトを設定した方がよいです。
    RewriteEngine on
    RewriteRule ^index\.rdf$ <新FeedのURL> [L,R=permanent]
    RewriteRule ^index\.xml$ <新FeedのURL> [L,R=permanent]
    RewriteRule ^atom\.xml$  <新FeedのURL> [L,R=permanent]
    
    Redirectでもできますからお好みで。

さてこの作業を行うと、ただでさえ遅かったBloglines(多分他のWebでサービスしているRSSリーダーも)の更新がより遅くなります。私の作ったFeedを適当な間隔でFeedBurnerがフェッチして二次公開し、それをBloglinesが1時間ないし2時間に一回フェッチするという二段構成になりますから。ただし、Ping-o-Matic!に更新Pingを打てばFeedBurnerに更新が即時に伝わって即フェッチに来ます。したがって一応二次公開に伴う遅延は限定的です。この場合、むしろMovable Typeが新規投稿時にしか更新Pingを送らないこと、従来からあるRSSリーダーの巡回遅延が大きいことの二つが問題です。

前者を解決するにはパッチを当てるかプラグインを入れるかして機能拡張する必要があります。

Ogawa::Buzz: Update-n-Ping Plugin

後者に関しては、私の場合2日に一度も更新しないので構いませんが、そのうちブレイクスルーが起きて如実に速くなることに期待しています。

また、Bloglinesの旧Feedに対するsubscribe情報は、新Feedに書き換わったみたいです。これを自動的にやるのは無理っぽい気がするので中の人が作業してくれた(=301 Redirectを検出してマージしてくれた)のだと思います。あるいは全読者が一斉に移行作業をしてくれたとか?アリエナーイ。

RSSリーダーを使っている読者様はお手数ですが下記URLから購読くださるようお願いいたします。

http://feeds.feedburner.com/ogawa

おまけ: RSSBarについて

FeedBurnerを使うとこのようにRSSリーダーごとの振る舞いも見られるわけなのです…。

しかし…、RSSBarというリーダーはユーザーベースでのシェアは3.6%(=6人/167人)なのですが、Feedのダウンロード回数でのシェアは43%(=478回/1112回)もあるのですね。24時間リーダーを使っていたとしても18分に一回クロールに来ている計算になり、他のツールと比較すると尋常でない頻度です。If-Modified-Sinceヘッダ付きで取りに来ているでしょうから、ほとんど304 Not Modifiedが返っているのでしょう。だけど、一方でリクエストしているクライアント側もそれなりの負荷がかかるわけで、遊休PCを使っているわけなのかしら?

こういうデータが見られるのは面白いです。