2009年5月2日土曜日

Pipeを使ってみた



つい最近知ったのですが、Yahooの運営するPipe(http://pipes.yahoo.com/)というサービスが最高に面白いです。


■そもそもPipeって何?
Pipeは、「数々のWebサービスが提供するRSSフィードなどのデータを簡単に加工して、別のRSSフィードなどのデータに変換して出力することができるサービス」です。「データ取得元」や、「繰り返し」、「文字列加工」や「URL生成」などのパネルをパイプでつないで、簡単なWebアプリケーションみたいなものを作ることができます。
もちろん無料です。必要なのは米Yahoo(http://www.yahoo.com/、日本のYahooではダメです)のアカウントだけ。
サーバー代金もいりません。好きなだけ新しいPipeを作ることが出来ます。


■さっぱりわからない。Pipeを使えば何が出来るのか具体的に知りたい。
たとえばこんなことが出来ます。
  • ニコニコ動画のマイリストIDを入力すると、マイリストのRSSフィードを生成して返すアプリを作ることが出来る。
  • ニコニコ動画のユーザーIDを入力すると、そのユーザーが公開している全動画のnicomimi(http://www.nicomimi.com/)へのリンクを自動的に生成してRSSフィードとして返すアプリを作ることが出来る。
  • ニコニコ動画の本日のランキング動画一覧から、タイトル・タグ・本文のいずれかに「東方」が含まれていて、再生回数が2万を超えている動画だけを抜き出してRSSフィードとして返すアプリを作ることが出来る。
ね?便利でしょ?


■わかったけど、それって難しくない?
では試しに、ニコニコ動画のマイリストIDを入力すると、マイリストのRSSフィードを生成して返すアプリを作ってみましょう。
Pipe(http://pipes.yahoo.com/)にアクセスして、Yahoo.comのIDでログインして、Create pipeってボタンを押して、何も考えずに左のサイドバーから以下のようにパネルを並べます。


簡単に説明すると、
1.マイリストIDをユーザーにテキストとして入力させて、
2.入力値を元に、ニコニコ動画のマイリストRSS取得用のURL(http://www.nicovideo.jp/mylist/5221166?rss=atom)を生成して、
3.URLからRSSフィードを取得して、
4.そのまま出力しているだけです。

実行結果はこちら。


ばっちりです。所要時間10分。サーバーの設定もデプロイも面倒なコーディングも一切いりません。デバッガも標準で付属(Pipe作成中にパネルをクリックすると実行結果がその場で見られる)。マウス操作だけで簡単に作れて、見た目がそれっぽいダイアグラムになるので、自分の作りたいWebサービスのちょっとした動作確認にも使える気がします。駆け出しのWebプログラマが、マッシュアップのセンスを磨いたりするのにも適していると思います。


■問題点
問題点もあります。主に日本人が使う上での問題点なのですが、
  • 全部英語
  • そもそも使いたいサービスがAPIやRSSフィードを公開していないと使えない
そう、使いたいサービスがAPIを公開していないケースが余りにも多い。ニコ動もキーワード検索結果がRSSで出ませんし、pixivに至ってはそもそもAPIの概念自体が無い。これでは「指定したマイリストIDのマイリスのうp主コメ中にpixivへのリンクが存在したらリンクをたどってpixivユーザーのIDを抜き出し画像全部RSSフィードとして取得する(ついでにお気に入りにも突っ込む)」みたいなアプリが作れません。逆にいえばAPIやRSSフィードのあるサービスであれば可能性は無限大です。サービスの提供している検索結果一覧やRSSフィードの内容が気に入らないなら、自分でPipeを書いて自分の好きなように調整すればよいのです。

Google App Engineで、index.yamlに記述したインデックスが正しく生成されないときの対処法



Google App EngineでDatastoreのindexを利用したアプリケーションを作成していたのですが、運悪くindexの生成がいつまで経っても終わらない現象に見舞われてしまいました。データ量はたかだか1000件程度しかないのですが、3日経ってもindexの状態が"Building"のまま。Googleグループの書き込みを見ると(http://groups.google.co.jp/group/google-appengine/search?group=google-appengine&q=index)、indexの生成に失敗するというケースがたびたび発生しているようです。
  • index対象となるモデルの数は全く関係がない。数件しか保存されていないモデルに対してindexを生成しても発生する。
  • Googleの中の人曰く、indexはアプリ開発者全体で共有のindex作成クローラーによって行われているため、全体的に一度に利用する人が増えると不安定になる。

■まずはappcfg.pyを利用して、indexを消して再生成してみる
まずはindexをいったん消して再作成することにより、自分の手で解決できないかどうか試してみます。こちらの記事(http://osima.jp/blog/gae-index-in-trouble.html)を参考にさせていただきました。

まずは、index.yaml中のトラブルを起こしているindexをコメントアウトして削除し、
# Get a list of articles for "all" news page.
#- kind: Article
# properties:
# - name: is_duplicated
# - name: date_update
# direction: desc

ターミナルから以下のコマンドを実行。
appcfg.py --force vacuum_indexes /path/to/my/application

うまくいけば、管理者コンソールのIndexesメニューを開くと、対象のindexが"Deleting"という状態になっているはずですので、しばらく待って完全にindexが消えてからindex.yaml中で再度コメントアウトした記述を復活して、
appcfg.py update_indexes /path/to/my/application

を実行すれば、無事にindexが再作成されます。


■それでもだめなら、GoogleグループからGoogleの中の人にお願いして消してもらう
これでうまくいけば万事解決なのですが、ときどきこの方法ではうまくいかない場合があります。たとえば私の場合は、下記のようなエラーが出て上手くindexの削除が出来ませんでした。
akisute $ appcfg.py --force vacuum_indexes .
Fetching index definitions diff.
Deleting selected index definitions.
2009-05-02 12:48:33,476 WARNING appcfg.py:670 An index was not deleted. Most likely this is because it no longer exists.

kind: Article
properties:
- name: is_duplicated
- direction: desc
name: date_update

このような場合は、2009/05/02現在、米国本家のGoogle App Engineグループ(http://groups.google.co.jp/group/google-appengine)に直接お願いしてGoogleの中の人によってindexを削除してもらうしかないようです。以下の点に気をつけて新規ディスカッションを投稿すれば、スムーズにindexを削除してもらえると思います。
  • indexの生成がBuildingのまま進まない、24時間以上経っているのにうんともすんとも言わないことを明記する
  • appcfg.py vacuum_indexを試したけれどもうまくいかなかったことを明記する
  • 自分のアプリのApp IDを載せる
  • どのindexを削除してもらいたいかを載せる
参考までに、Google App Engineグループをindexで検索したときの結果(http://groups.google.co.jp/group/google-appengine/search?group=google-appengine&q=index)を載せてみました。同様の症状例がたくさん報告されていますので、それらの文面を適当にパクって参考にして投稿するのをおすすめします。
ただし、
Before posting, please read our Charter. Please note that due to recent spam activity, a member's first post will be moderated by one of the group's managers.
と注意書きがあるとおり、現在Spam対策として、最初の1回目の投稿はモデレータによってチェックされてしまい、すぐに投稿が反映されないみたいです。投稿されたとしても、いつindexの削除をしてくれるかはGoogleの中の人の気まぐれになってしまうので、解決には少々時間がかかります。


■英語が苦手なら、日本のコミュニティに助けてもらおう!
どうしても英語が苦手なら、日本のGoogle App Engineコミュニティ(http://groups.google.co.jp/group/google-app-engine-japan)に相談してみるとよいかもしれません。たとえば、こちらの投稿(http://groups.google.co.jp/group/google-app-engine-japan/browse_thread/thread/289b87a344715ea1/c9b5f8e394ac6a47)が参考になります。


■でも本当は
早くこんなトラブルが起こらないようなシステムになってほしいです><

2009年4月26日日曜日

MacPortsを使って、Pythonの開発環境を整えてみた

ここ最近勉強会続きだったため、複数のバージョンのPythonの開発環境の整備をする必要に迫られました。
まずはPython2.6.2をインストールしようと考えたのですが、python.orgからdmgでダウンロードしてインストールすると余計な物をたくさんインストールされてしまいますし、何より環境の切り替えが大変です。
(Mac付属の2.5.1でないとDjangoがエラーを吐いたりするため、いつでも2.5.1に切り戻せるようにしたい)

そこで今回はMacPortsを使って開発環境を整えてみました。

■Pythonのインストール
これはMacPortsから以下のコマンドを実行するだけでいけました。
sudo port install python26

ただ、依存するモジュールが非常に多いためビルドに大変時間がかかりました。MacBook Airで、およそ1時間ぐらい。
これで/opt/local/Library/Frameworks以下にPython.frameworkがインストールされるのですが、インストールしただけでは自由に元々存在するPython 2.5.1との切り替えができません。
そこで、同じくMacPortsで提供されている、python_selectというスクリプトをインストールします。
sudo port install python_select

インストールしたら、以下のようにして自由にPythonのバージョンを切り替えることが出来ます。
$ python_select -l #利用可能なバージョン一覧を表示
Available versions:
current none python25-apple python26
$ python_select python26 #python2.6に切り替え

こいつは大変便利です。

■Djangoのインストール
DjangoもMacPortからインストールできます。
sudo port install py26-django

Djangoだけではなく、jinjaやSQLAlchemy, Werkzeugなど、名前の知られているPythonのフレームワークはすべて存在しているようです。とっても楽ちん。
ちなみにインストールできるportとしてpy25-djangoのようにPythonのバージョンを指定しているものと、py-djangoのように指定していないものがありますが、py-djangoをインストールしようとすると突然Python2.4をインストールしようとしやがりましたので、基本的にはPythonのバージョンを指定しているportを選んだ方が良さそうです。

さて、MacPortでインストールしたPythonのためにDjangoをインストールするのは簡単でしたが、
問題になってくるのは元々標準で入っているPython2.5.1のためにDjangoをインストールするときです。
easy_installが使えるようなので、今回はeasy_installを使ってインストールしました。
sudo easy_install django

ただしportと比較すると後からアンインストールするのが面倒だという欠点があります。portが使えるならportがいいですね。

■PILのインストール
PILのインストールも基本はMacPortで。
sudo port install py26-pil

問題はPython 2.5.1にインストールするときです。私の環境では、easy_installが失敗してしまい簡単にインストールできませんでした。
悩んだあげく、PILのウェブページからPython Imaging Library 1.1.6 Source Kitをダウンロードし、直接setup.pyを実行して解決しました。
tar zxvf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6
sudo python setup.py install