preload
2月 25

実は前から公開してたんだけど、最近の機種情報を追加ついで、あと Rails のプラグインを書く勘を取り戻しついでに、ちょっと手を入れたので、改めて紹介しときます。

mbterm_db は Ruby on Rails でケータイサイトをつくる際に、ブラウザのバージョンや画面サイズを取得する Rails プラグインです。

このプラグインは、以前モバイル勉強会で紹介した機種情報 DB の出力の一形式です。機種情報 DB には、基本的に僕が必要なものしか入れてないのですが、最近は FlashLite に傾倒気味なので、そのうち FlashLite のバージョンくらいは入れるかもしれません。

こんなデータベースを持たずとも、ドコモ以外は HTTP リクエストヘッダにそこそこの情報が含まれているのですが、リクエストヘッダの情報は微妙に足りなかったり(一行の文字数とか)、SSL したら取れない事があったりと(SoftBankでたまにある)、結構ハマりがちです。まあ、あったらあったで越したことはないかな、ということで、ご入用の方、どうぞお持ちください。

インストール方法は以下の通り。詳しくは trac の方をご覧ください。jpmobile とか Mobile_on_Rails などのプラグインと併用するのも便利だと思います(使わせていただいてます。感謝! ;-)

$ script/plugin install http://jpmbdb.googlecode.com/svn/trunk/mbterm_db

Continue reading »

Tagged with:
2月 19

Rails や TMail を使った Ruby アプリケーションで携帯メールをさばこうとするとブチ当たる、" 3つ以上連続するドットを含むメールアドレス問題 " の解決方法を再生産したので晒してみます。一応幾つかテストかけて使えてるけど、おかしかったらツッコミください。

まず、TMail::Mail.parse したときのエラーメッセージから:

NoMethodError: You have a nil object when you didn’t expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]

これを追っていくと、parser がパースに失敗しているところに行き着く。で、これに対して urekatのスカンク日記3 さんが紹介されているのは、parse 時の Syntax Error を rescue して、「あいまいパース」に落とすエレガントな方法。

プログラマ 福重 伸太朗 〜基本へ帰ろう〜 さんが紹介されているのは、先にアドレスをチェックして、必要に応じて ActionMailer を使わない方法へ回避する、これまたイカした方法。

で、ここで紹介するのは、TMail の parser を書き換えるという方法。
もうちょっと具体的に言うと TMail がメールアドレスのパースに使っている parser.rb – これが Racc というパーサジェネレータで生成されているのだが – の生成元: parser.y を改造してしまう、という方法です。つまり、これをやっちゃうと、同じ稼働環境で動いてるアプリ全体のメールアドレスの parse に影響するので、その辺覚悟してお試しを。

まず、TMail のアーカイブを拾ってきて、以下の通り tmail-1.2.1/lib/tmail/parser.y を書き換える。

$ diff parser.y.org parser.y
211c211,217
< | local_head '.' { val[0].push ''; val[0] }
---
>        | local_head dots
>                 {
>                   val[1].times do
>                     val[0].push ''
>                   end
>                   val[0].push ''
>                 }
235,236c241,242
< dots      : '.'     { 0 }
<             | '.' '.' { 1 }
---
>   dots      : '.'      { @dotnum = 0 }
>             | dots '.' { @dotnum = @dotnum + 1 }

ここで対応したのは、「3 つ以上連続したドット」への対応と、「@ (アットマーク) 直前で連続するドット」への対応の 2 点。(他にもケータイ特有な不可思議なフォーマットがあるかもですが、ここではスルー)

TMail の parser は、ドットふたつには対応していたが、ドット 3 つ以上の場合に対応する生成規則が無い ( dots ‘.’ から dots への還元ができない) ために parse error が起こっていたようだ。

アドレス中の文字列は逐次配列に push され、Address が new されるときに、配列要素の間にドットを入れる (空要素が入っていたら、ドットを一個追加する) という動きをしているようだったので、後半の書き換えで、連続するドットの数をカウントし、local_head への還元時に配列を組み立てるようにした。

前半の書き換えは、local 変数 ( @ の直前) として local_head ‘.’ と、ドットひとつしか許していないようだったので、これを同様に dots 変数を受け付けるようにしたもの。

あとは、こいつを make してやって( make には Racc が必要)、出来上がった parser.rb と parser.y を gem のパスでもどこでも適切なところに置いてやれば OK 。ActionMailer は内部 vendor ライブラリに TMail を包含しているので、必要であれば、そっちも書き換えてやる。(試しに消してみたら、gem の下の TMail を見に行ってくれたみたい。)

この方法のメリットは、サーバ環境を自由に使って良い人なら簡単にできちゃうってこと。デメリットは、これでいいかどうか自信が無いっていうのと、サーバ環境共有してる他のアプリにも影響がおよぶこと、あと、gem update tmail とかやったら元通りになっちゃうってこと。

TMail の過去の修正では、ドット 2 つに対応しているので、RFC 非準拠でもやむなく対応したのかと思っていたが、オリジナルの dots の生成規則を見るに、どうも不本意な実装になっているように見えた。が、この対応方法で合ってるかどうかもよくわからないので、作者さんに連絡する前に、とりあえずここで紹介してみましたです。

Continue reading »

Tagged with:
2月 18

なんと、第27回とのこと。長く続けられている運営の皆様に感謝&尊敬。今回は、霞ヶ関 CTC さんのセミナールームっぽいところをお借りしました。ありがとうございます。

Ruby 関連のこういう勉強会は、今回初めての出席。今回おこなわれた Rails 勉強会は、冒頭、その日のセッションを前後半、幾つかの部屋に分けて募り、いずれかにサインアップしていくという方式。こういう方式のおかげで、Rails 歴の短い僕も、自分のレベルに合うセッションに参加させていただく事ができた。こういう運営はうれしいなあ。

前半は、先日公開された fastladder のソース読み。こういう面白い教材をオープンにしてくれたなかのひとに感謝!一応手元の MacBook で動かせるようにして、gonzui でソース読みの環境を作ってから臨んだ。進行は井上さん。始めに E-R 図で全体のモデルを確認してから、サインアップ〜ユーザ認証〜セッション管理周りを追っていく。認証は AuthenticatedSystem を使ってて、特にトリッキーな部分は無く、素直な実装だった。元が Perl アプリだから当たり前か。Application.rb で before_filter :set_member してて、毎アクセスごとに DB 問い合わせしてユーザの正当性をチェックするような実装になってるみたい。
認証周りだけだと時間が余ってしまったので、lib/crawler.rb も追ってみたい、とお願いし、一緒に読むことになった。サーバサイドだと、クローラの実装周りが面白いところなんじゃないかな、と思って読んでみたけど、こちらもそれほどトリッキーな部分は見当たらなかった。フィードを取得するリクエストの発行部分のタイムアウト値の制御周りや、almost_same みたいなフィードの中身チェックの部分が結構興味深かったかな。本家の方には、まだ明かされてないいろんな工夫があるんだろうな〜。
そうそう、favicon を取得変換する辺りのメモリ使用量について話題になった。僕はこの件なにも追ってなかったんだけど、言われてるような FreeImage の問題なのかな?
メモリ使用量を 10 分の 1 にした shunirr.org さんによれば:

まぁ、favicon取得は新規サイトを登録した時だけだろうと思うので、たぶん2回目以降のくろうるからはメモリ使用量は大して変わらないと思いますけどね。

とのことだけど、どうも update の都度 favicon を見に行ってるように見えるなあ。 (ざっと読んだだけなので、ひょっとしたら違うかも。) subscription のときだけでもいいようにしたら、どうなるかな。
せっかくサーバサイドもセットで公開してくれたんだし、JavaScript 側も含めていろいろいじってみようかな。

後半は、舞波さんによる ActiveScaffold の紹介セッション。去年の8月くらいに ActiveScaffold をちらっと使ってみたけど、カスタマイズの仕方がよくわからなくて、結局放置してた。(ほぼ)ノンカスタマイズで使うときは Streamlined を使っていたので、良い機会だった。
使いはじめが scaffold と同じで簡単なことや、リレーションを動的に解決してくれることは知っていたが、ここまでいろいろカスタマイズできるとは知らなかった。active_scaffold :モデル名 でブロックへ渡してごりごりカスタマイズ。この第一歩がわかっただけで、すげーテンションが上がった。この一歩がわかれば、ドキュメントもソースもどんどん読める!いやー、ActiveScaffold ってスゴいんですね〜。

最後は、KPT (Keep, Problem, Try) と題した、運営の振り返り。前半後半の終わりにも、各セッションでどういうことが話されたかの振り返りの時間があったんだけど、こういうのも含めて、運営がしっかりしてるなあとおもった。27回も続いているのもうなずけます。

いつもブログ拝見してるような方々も来られてて、なんだかとても有意義な時間を過ごさせていただきました。今日は終わってから用事があったので懇親会は行けなかったんだけど、次回は懇親会も行きたいな〜。それから、なんかネタ提供してしゃべれるようにならないと。

Tagged with:
1月 24

(2008/01/29 追記: 下記の内容は 2008/01 下旬より公開されている FMS-3.0 developer edition でも同様に利用できる事を確認しました。H.264 のストリーミングはまだ試してません。)

post 忘れてた。正月に前々から触ってみようと思ってた Flash Media Server 2 (FMS) をいじっていたので、そのときのメモ的な何か。まずは Ubuntu-7.10 に FMS を突っ込んで、FLV をストリーミング再生するところまで。

FMS は Adobe が提供しているメディアストリーミングサーバ。平たく言うと RTMP というプロトコルを喋るサーバ。開発/検証目的、非商用であれば、接続数に制限のある developer edition が無償で利用できる。詳しくは本家のライセンス参照。ちなみに、そろそろ、FMS3 の developer edition が出てきそうなので、そうなると、この情報は古いものになるかも。(2008/01/29 追記: このエントリの範囲であれば、そのまま利用できます。バージョン番号やファイル名は適宜読み替えてください。)

まずは adobe から FMS2 の developer edition (linux) をダウンロードしてきて、伸張、インストールスクリプトを実行。

$ tar xzf FlashMediaServer2.tar.gz
$ cd FMS_2_0_3_r68_linux
$ sudo ./installFMS
ERROR: Your distribution, unknown, is not supported by this
Macromedia Flash Media Server installer.

対象環境(Redhat) じゃないからダメって怒られた。とりあえず、無理矢理入れるオプションでもないかインストールスクリプトを眺めてみる。–platformWarnOnly ってオプションを発見。

$ sudo ./installFMS -platformWarnOnly
WARNING: Your distribution, unknown, is not supported by
this Macromedia Flash Media Server installer.
:
To install Macromedia Flash Media Server now, press ENTER.
To cancel the installation at any time, press Control-C.

なんか動いてるぽい。以降、適当に聞かれる項目に答えていけばインストール完了。owner とか実行権限は apache とかと同じになるように変更した。設定した項目のサマリは次のとおり。(以下、インストールディレクトリを ${FMSROOT} と表記。)

----------- Install Action Summary -----------
directory                      = ${FMSROOT}
FMS Server Port                = 1935
FMS Admin Server Port          = 1111
Administrative username        = fms
Administrative password        = (suppressed)
FMS owner                      = www-data
FMS service user               = www-data
FMS service user group         = www-data
FMS run as daemon              = Yes
Start FMS                      = Yes

なお、この辺りは設定は ${FMSROOT}/conf 以下に xml 形式で保存されているので、後でも変更可能。インストールした FMS は、

$ sudo /etc/init.d/fms start

これで起動できる。さて、同梱されている ${FMSROOT}/fms2_console.htm を使うと管理画面に接続できるらしい。
${FMSROOT}/fms2_console.swf と一緒に適当な場所に置いて、ブラウザでオープン。fms サーバのアドレスと administrative username/password を入れて接続。おや、繋がらない。起動してないのかな??ログも何も出てないから分からん。/etc/init.d/fms を追って、起動プロセスを確認してみる。${FMSROOT}/server start -silent で実行してるみたい。これを直接呼んでみよう。

$ sudo ${FMSROOT}/server start
ulimit: 13: Illegal option -u
[: 16: 32768: unexpected operator
NPTL 2.6.1
./server: 49: Syntax error: Bad substitution

Bad substitution らしい。該当の箇所はココ。

48: # if tmpdir doesn't end in a slash, add one
49: lastchar=${tmpdir:${#tmpdir}-1:1}

:( コロン)で書いてる変数の展開辺りが怪しいな。bash では使えたと思ったけどな.. と思って、ファイルの頭を見たら

1: #!/bin/sh

おや、

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2007-05-05 18:28 /bin/sh -> dash

む、dash 環境だったのか (^^; dash はコロンを展開してくれないのかしらん。試しに server と、あと adminserver の一行目を

1: #!/bin/bash

と書き換えてみる。$ sudo ${FMSROOT}/server start 。お、うまく起動してるぽい。今度こそ fms2_console.htm から接続.. お、それっぽい画面が出た!

では、適当な動画をストリーミング配信してみる。配信素材は、ごにょごにょして入手した flv 。FMS は ${FMSROOT}/applications ディレクトリ以下をアプリケーションと認識するので、ここに個々のアプリケーションディレクトリを作成していく。今回はストリーミング配信テスト用のアプリケーションを作成するので、こいつを stream_test とする。

$ cd ${FMSROOT}/applications
$ mkdir stream_test

アプリケーションディレクトリ以下で、FMS はインスタンスという実行単位を持つ。クライアントは、アプリケーションを利用するときにインスタンス名を指定する事ができるし、インスタンスが無い場合は、FMS にデフォルトのインスタンス名でインスタンスを生成させる事もできるし、あらかじめいくつもインスタンスを作っておく事もできる。この辺りの構成がスケールアウト時の処理分散に効いてくるのだろう。ここでは、inst という名前でインスタンスを作成。

$ cd ${FMSROOT}/applications/stream_test
$ mkdir inst
$ mkdir -p streams/inst

こんな感じで、stream_test 直下にインスタンス名のディレクトリと streams/<インスタンス名> のディレクトリを掘る。FMS はサーバサイドでのスクリプト実行をサポートするが、今回の命名のケースだと、${FMSROOT}/applications/stream_test および ${FMSROOT}/applications/stream_test/inst にアプリケーションスクリプト、${FMSROOT}/applications/stream_test/streams/inst 以下にストリーミング配信する素材を設置していく事になる。今回は video.flv を ${FMSROOT}/applications/stream_test/streams/inst へ設置した。

サーバサイドの設定は、もう 1 ステップあるのだが、次に Flash IDE を用いて、動画視聴用のアプリ(swf) を作成する。今回は CS3 を利用。体験版でも OK。
[ファイル]-[読み込み]-[ビデオの読み込み] で、[Web サーバー、Flash ビデオストリーミングサービス、または Flash Media サーバーに展開済み] リソースの URL として、設置した video.flv の URL を指定する。今回の場合、rtmp://<FMSサーバアドレス>/stream_test/inst/video.flv となる。streams ディレクトリを指定する必要はない。URL を指定したら視聴用 swf のテンプレートを適当に選べば、swf のベースができる。このままでも良いし、好きなようにデザインを入れてもよし。できあがったら、保存 - パブリッシュして、生成された swf やら js, html ファイルを http アクセスできる箇所へ運ぶ。作成した swf を stream_test.swf とする。

さて、これらのテンプレートは、FLVPlayback と呼ばれるコンポーネントを利用しているので、こいつが話し相手になるサーバサイドスクリプトが必要になる。これは Flash 8 の IDE には付いていたらしい(CS3 にもあるらしい)が、僕のインストール環境には見つからなかった。Flash Media Server Developer Center から辿っていって、サンプルをようやく発見 (ここまでたどり着くのに大変だった..)。この Samples.zip を伸張して得られる、Samples/ComponentsAS2/FLVPlayback/main.asc が目的のものになる。これをサーバ側に設置。最終的なサーバ側のファイル配置は次のようになる。

${FMSROOT}/applications/stream_test/
|- main.asc
|- inst/
|- streams/
|- inst/
|- video.flv
htdocs/
|- AC_RunActiveContent.js
|- stream_test.swf
|- stream_test.html
|- SkinOverPlayMuteCaptionFull.swf

これで、htdocs 以下の stream_test.html にブラウザでアクセスすれば、FMS への接続後、ストリーミング再生が確認できる。再生中に fms2_console.htm で管理画面を確認すれば、接続数やら配信レートやらも確認できる。以上、おわり。

余談だが、こうやっていじっていくなかで、システムアーキテクチャを掴み、サーバサイドでのアプリケーション定義方法やらインスタンスの概念やらを見ながら、プラットフォームの設計思想を想像していくのは、なかなかに面白い。去年 Adobe MAX に行ったときにあまり分からなかったところも、ちょっとは理解できるようになったかな〜。

この後、VLC やら ffserver とかの配信環境の実験もやってみた。そっちは気が向いたらまとめる。

ケータイにも FlashLite 3.0 が載ったし(FLV 今んとこダメだけど)、今年は、ケータイでの動画視聴がもっと盛り上がってくると思うんだな〜。というわけで、PC でもだいぶシェアが高いし、恐らくケータイでも動画配信プラットフォームの本命になっていくであろう Flash ベースの動画配信環境についての実験でした。

参考:

Tagged with:
1月 21

ここのデザインを変更がてら、自サイト(tmty.jp) 配下のコンテンツを巡回していたら、trac がエラーを吐いていた:

Python Traceback

Traceback (most recent call last):
File “/home/****/local/lib/python2.4/site-packages/trac/web/main.py”, line 406, in dispatch_request
dispatcher.dispatch(req)
File “/home/****/local/lib/python2.4/site-packages/trac/web/main.py”, line 191, in dispatch
chosen_handler = self._pre_process_request(req, chosen_handler)
File “/home/****/local/lib/python2.4/site-packages/trac/web/main.py”, line 263, in _pre_process_request
chosen_handler = f.pre_process_request(req, chosen_handler)
File “/home/****/local/lib/python2.4/site-packages/trac/versioncontrol/api.py”, line 73, in pre_process_request
self.get_repository(req.authname).sync()
File “/home/****/local/lib/python2.4/site-packages/trac/versioncontrol/api.py”, line 91, in get_repository
raise TracError(‘Unsupported version control system “%s”. ‘
TracError: Unsupported version control system “svn”. Check that the Python bindings for “svn” are correctly installed.

これまで問題なかったのに、svn が Unsupported とか言い出してるのは妙だ。python が svn 連携に失敗しているのかな?
試しに、python のコマンドライン実行で確認してみる。

$ python -c “from svn import client”
:( 略)
… Shared object “libintl.so.6″ not found, required by “_client.so”

なんかいっぱいエラーが出たが、Shared object が無いって、なんで今更突然こんなエラーが出るようになっちゃったんだろ。最近サーバ設定いじった記憶ないし.. と、さくらのニュースアーカイブを見に行ってみたら、メンテナンス通知が出てた:

平素はさくらインターネットをご利用いただき、誠にありがとうございます。
さくらのレンタルサーバサービスにおきまして、サービスの安全性の向上を
目的とした、OS のバージョンアップを実施いたします。
ご迷惑をおかけしますが、ご協力お願いいたします。
:( 中略)
1/15(火) www731 〜 www740.sakura.ne.jp
1/16(水) www741 〜 www755.sakura.ne.jp
1/18(金) www756 〜 www770.sakura.ne.jp
:( 中略)
主な変更:

OS FreeBSD 4.10 → 6.1
:( 後略)

うお、もろ該当サーバに入ってた。これは影響でかいだろー。知らなかった.. サーバメンテの通知は、ちゃんとチェックしとかなきゃダメっすな。(でも、メールとかでリマインドしてくれても良いのになー。掲載から作業日程短すぎな気がする。)

4.10 => 6.1 での細かい変更点までは追ってないが、恐らくユーザインストールしたアプリ周りは、ほぼ reconfigure/rebuild が必要になるだろう。ということで、再設定開始。さくらのレンタルサーバでは、python は最初から入ってる(ユーザインストールしたものではない)ので、subversion 周りの reconfigure から開始。設定は覚えてなかったので、config.log で configure オプションを確認してから、SWIG-1.3.21 を $ ./configure && make && make install 、続いて、subversion-1.2.3 を $ ./configure && make && make install && make swig-py && make install-swg-py と。あと、念のため、svn-python/svn 以下の symlink を貼り直した。

とりあえず、こんだけで $ python -c “from svn import client” が通り、trac も動くようになった。

が、1/21 5:04 現在、機種情報検索サービス(rails環境)が復旧できてない。ruby/gem 周りも一通り再設定して、アプリ自体は script/console 環境下で問題なく動いているんだが、Web 経由で DB アクセスが発生するようなリクエストを投げると 500 になっちゃう。apache のエラーログって拾えないのかな?rails のログにはエラーが落ちてないんだが、DB アクセスしない範囲のリクエストは正常にさばけてるるっぽい。CGI 経由で DB に行ったときだけ利いてくる設定って.. どこだ?apache ログが拾えないと切り分けできないかな?うーん.. と、ここで力尽きたので、続きはまた今度。求む識者。

(2008/01/25 追記) その後.. とりあえず解決:

Continue reading »

Tagged with: