一般的な Web Programmer ならば、HTTP Status code はすべて暗記していると聞きました。
しかし、僕は初心者なので、なかなか覚えきれていないので、HTTPのステータスコードをさがすのに便利なツールを用意しました。httpstatusです。インストールはJSX(npm install jsx)とgitが使える環境で:
$ git clone https://github.com/shibukawa/oktavia
$ cd oktavia
$ make
です。使い方はコマンドの後ろに検索ワードを書けばいいのですが、Googleの検索と同じようなクエリーも少しだけサポートしています。本当はダブルクオーテーションでくくるとそのフレーズを完全に含む検索もいれたかったのですが、JSXにパラメータが渡ってくる時点でダブルクオーテーションが消えてしまうので判別が不能・・・
$ ./httpstatus ok #okを含む行
200: OK
$ ./httpstatus 40 -not #40を含むけどnotを含まないステータス
400: Bad Request
401: Unauthorized
402: Payment Required
403: Forbidden
407: Proxy Authentication Required
408: Request Timeout
409: Conflict
$ ./httpstatus ok OR not # okかnotのどちらかを含むステータス
200: OK
406: Not Acceptable
405: Method Not Allowed
510: Not Extended
404: Not Found
501: Not Implemented
304: Not Modified
416: Request Range Not Satisfiable
505: HTTP Version Not Supported
オプションなしで実行すると、すべてのステータスの一覧とともに、今日のあなたの運勢にピッタリなステータスコードを1つピックアップして表示してくれます。僕の今日の運勢は「Today's status: 503: Service Unavailable」でした。
JSXというエラーを見つけてくれて、JavaScriptよりもデバッグがラクな言語で書きました。JSも生成できます。ちょっとソースコードは長くなっちゃったので、割愛しますが(github参照)、言い訳をすると、もともとJSXでFM-indexを使った全文検索エンジンを作っていまして、これもそれを内部で利用しています。
FM-indexは日本に出張中に買ってみた高速文字列解析の世界という本で紹介されていた検索のアルゴリズムです。圧縮インデックスを使った全文検索です。転置インデックスを使う方式と違って、検索するだけならキーワードに分割しておく必要がありません。そもそもキーワード分割の難易度が高く、10MBだかの辞書を装備したMeCabさんに協力してもらわないと満足に分割もできない日本語だと、ブラウザ上でちょろっと精度よく分割というのは難しかったりします。それをしなくてもよい!しかも2-gram, 3-gramとかと違ってインデックスが圧縮されていて小さいですし、一文字でもマッチさせられます。また、圧縮されているインデックスから元の文章を復元できます。ドキュメントツールのSphinxだと、検索後のページサンプル表示に、元のソースのテキスト(.txtとしてアップされている)を利用します。これだと、翻訳機能と相性が悪い(元のソースは別言語)し、ソースをエクスポートする機能を有効にしないと検索機能が弱くなるという欠点があります。FM-indexならその部分も解消できる!まさに、Sphinxのブラウザ上で動く検索エンジンのためのアルゴリズムといえます。FM-indexに関してウェブで読める記事としては@echizen_tmさんのこの解説が分かりやすいですが、ちょっとまだ完全に理解できてない部分もあってまだまだコードを書きながら勉強中です。
現在は@echizen_tmさんのShellinfordをベースにいろいろ改造中です。Shellinfordの場合は、ドキュメントという区切りの情報を持てて、検索結果ではドキュメントのインデックスを返したり、インデックスを使って元のドキュメントのコンテンツを復元できるようになっていましたが、Oktaviaではこの部分をいろいろなケースに対応できるように自由に情報を付与できるように拡張しています。以下の4パターンを実装しています。Table以外は組み合わせて利用できます。今回はSplitterを利用して、行ごとに検索結果をマージして出すようにしています。
- Section: 名前付きのセクション。ドキュメント、タイトルの入ったセクションで利用することを想定
- Splitter: 名前なしのセクション。行番号、パラグラフ、分かち書きの単語区切りなどで利用することを想定
- Block: 名前つきのブロック。サンプルコードの箇所など、特定の範囲(スタートとエンドがある)を表すのを想定
- Table: CSVとかTSVみたいなデータで使うのを想定。row/column情報を返すことができる
現在はJSX実装のみですが、Sphinxに組み込んで使えたらいいな、ということでPython版も作りたいと思っています。
検索エンジンの作業の進捗としては、FM-indexのコア部分は動くようになっていて(@echizen_tmさんのFM-index紹介記事で書かれている線形探索な問題は今後修正が必要)、Snowballという由緒正しきステミングアルゴリズムに関連するツールのソースコードジェネレータを改造して、JSX版とPython版をそれぞれ生成できるようにしたのと、HTMLのパース用にJSのSAXParserをJSXに移植したり、node.js用のgetoptをJSXに移植したり、といった段階です。今はインデックス生成ツールをぼちぼち作成している段階です。クエリーのパーサ、スコア計算部分も追加して、最終的には、ブラウザで動く全文検索エンジンとして、Webサイトに簡単に組み込める部品っぽい形式でリリースしようと思っています。あとはインデックスを中間形式でSQLiteか何かにいれて、部分的なインデックスの更新をできるようにして、ExpressとかDjangoとかからサーバサイドの簡易全文検索ツールとしても使えるようにしてもいいな、とか。今回はhttpstatusというビッグウェーブに乗っかるために、急遽クエリーの簡易パーサだけ作って動くようにしたものです。最終形とはいろいろ異なると思います。まだまだアルファ版です。