今日は、MovableType ネタでいきます。
tools ディレクトリの下に何が入ってるか見たことありますか?
たぶん、"run-periodic-tasks" っていう、指定日投稿に利用するスクリプトを使ってる人は、一度は見たことがあると思うのですが。
よくみると、"convert-db" とか "mt-tmpl-preview" とか、"rebuild-pages" とか興味深いものもいくつかあります。
こちらでは、裏ファイルとか言われちゃってますね。
ちなみに、この tools ディレクトリ、バージョンが上がるごとに中身が増していますw
そして、MT 4.2 beta をみたところ、4.2 ではさらに数が増えるようで。
さらに謎なのが、この tools ディレクトリの中に含まれているスクリプト、そのままでは使えなかったりするのです。
何のために、tools ディレクトリを含めて配布しているのか、sixapart の中の人の真意は理解できませんが、勝手に弄り倒してくれ、という geek への挑戦状だろうか?
ということで、今回は "rebuild-pages" を使ってみたいと思います。
では、rebuild-pages がどんなものかを簡単に説明しておくと。
実行するだけで再構築できるスクリプトです。
cron とかに任せておけば、定期的に再構築とか、使い道はありそうです。
ですが、予想通り、そう簡単には使えないわけで・・
1. まずは下準備。
下調べした段階で、この "rebuild-pages" がそのままでは使えないことは理解済。
こちらが参考になります。
"rebuild-pages" の中身を見てもらえばわかるのですが (読めない人もいると思いますが) 、とにかく "LWP::UserAgent::Local" が必要なのです。
上のサイトに書いてあるとおり、sixapart のサイトからダウンロードしてきます。
cd /path/to/mt
cd extlib/LWP
mkdir UserAgent
cd UserAgent
wget http://code.sixapart.com/svn/movabletype/trunk/t/lib/LWP/UserAgent/Local.pm
とかやってあげるといいと思います。
だけど、これだけじゃまだ動きません。
"rebuild-pages" を少し書き換えます。
#!/usr/bin/perl
#use strict;
use lib qw(../lib ../extlib);
use LWP::UserAgent::Local;
.....
大体こんなもんで準備完了。
あとは、"rebuild-tools" のパーミッションを 755 とかに変えてあげれば。
さあ実行してみましょう。
2. やっぱりうまくいかない。
"rebuild-pages" は、パラメータとして username と password を与えてあげる必要があります。
ということで、実行例はこんな感じ。
./rebuild-pages user pass
さあ、こい!!と張り切るわけですが、なかなか粘ってくれるようです。
こんなエラーを吐いてきました。
# ./rebuild-pages hogehoge foobar
Couldn't spawn mt.cgi at ../extlib/LWP/UserAgent/Local.pm line 83.
さっき、sixapart からダウンロードしてきた "LWP::UserAgent::Local" で引っ掛かってるみたいですね。
ちなみに、このエラーも把握済みだったりする。
なんか、動かないと気が済まないぞ!
とりあえず、いろいろ見直してみましょう。
3. 絶対動かしてみせる!
戦いの始まりです。
まず、Local.pm を読むのは面倒なので、そのほかの部分から当たっていきます。
rebuild-pages の、この部分
my $url = http://localhost/mt/mt.cgi?__mode=rebuild&blog_id=$blog_id&type=$build_type&next=$next&offset=$offset&limit=$limit&total_entries=$total_entries&entry_id=$entry_id;
まず、僕のサーバーでは localhost でアクセスしても、MT にはアクセスできない。(バーチャルホストで...)
レンタルサーバーとかでも、これは一緒だと思う。
これが、さっきのエラーの直接の原因ではなくても、これでは動かないことは明らか。
ということで、localhost の部分を自分のサイトのアドレスに変更します。
僕の場合は、こんな感じ。
my $url = http://techno-st.net/mt/mt.cgi?__mode=rebuild&blog_id=$blog_id&type=$build_type&next=$next&offset=$offset&limit=$limit&total_entries=$total_entries&entry_id=$entry_id;
しかし、ほんと、これ作った人何考えてんだ?と言いたくなるような・・・。
その後、しばらく他もいじってみたんだけど、動きそうにもないので Local.pm に探りを入れることにする。
まず、エラーの発生している、83 行目、何をしているかというと
open RESPONSE, "./$script_name|" or die "Couldn't spawn $script_name";
こんなことをしている。
perl はあまり詳しくないけど、$script_name が open できなかったら死ね!!ってことってぐらいはわかる。
言葉が悪い?いや、そのままじゃないかw (perl ではよく使う?
じゃあ、$script_name は何?ってことになるんだけど、死んだ時にエラーを吐いてるわけでそれが
Couldn't spawn mt.cgi at ../extlib/LWP/UserAgent/Local.pm line 83.
これなわけ。
すなわち、mt.cgi が spawn できないってことらしい。
じゃあ、spawn ってなんじゃ?ってことになるんだけど、
なかなか理解不能なので、そこは置いておくとする。(生み出すとか、量産とか?
とりあえず、mt.cgi にアクセスできないってことらしい。
ここまでくれば、大体の人が気づくかな?
"./$script_name|"
"./$script_name|"
"./$script_name|"
./ ./ ./ ./ ./ ./ ./ .//////1[al;kedfaSD~ (壊
ん~、なんで同じディレクトリの mt.cgi なんか探してんだ?
もちろん、mt.cgi は、アプリケーションディレクトリの一番上にあるはずなので、Local.pm とか rebuild-tools などと同じディレクトリにあるはずがない。
まったく、やっぱり sixapart の人何考えてんだ?
さすがに、Local.pm を mt.cgi と同じディレクトリに持っていくわけにもいかないので、ここを書き換えることにする。
相対ディレクトリでもいいけど、まあ絶対ディレクトリで書き換えた方が安全かなぁとおもって
if ($request->content()) {
$ENV{CONTENT_LENGTH} = length $request->content();
my $pid = open2(\*RESPONSE, \*REQUEST, "/path/to/mt/$script_name")
or die "Couldn't spawn ./$script_name";
print REQUEST $request->content();
close REQUEST;
} else {
open RESPONSE, "/path/to/mt/$script_name|" or die "Couldn't spawn $script_name";
print STDERR "$script_name exit status: $?\n" if $?;
}
こんな感じにします。(76 - 85 行目)
4. 実行してみる。
全部終わったら、試してみよう。
# ./rebuild-pages user pass
とやって、
/mt/mt.cgi?__mode=rebuild&blog_id=1&type=Individual%2CMonthly%2CDaily%2CWeekly%2Cindex&next=1&offset=0&limit=&total=628&entry_id=&is_new=&old_status=&old_previous=&old_next=
/mt/mt.cgi?__mode=rebuild&blog_id=1&type=Individual%2CMonthly%2CDaily%2CWeekly%2Cindex&next=1&offset=2&limit=&total=628&entry_id=&is_new=&old_status=&old_previous=&old_next=
/mt/mt.cgi?__mode=rebuild&blog_id=1&type=Individual%2CMonthly%2CDaily%2CWeekly%2Cindex&next=1&offset=198&limit=&total=628&entry_id=&is_new=&old_status=&old_previous=&old_next=
/mt/mt.cgi?__mode=rebuild&blog_id=1&type=Individual%2CMonthly%2CDaily%2CWeekly%2Cindex&next=1&offset=556&limit=&total=628&entry_id=&is_new=&old_status=&old_previous=&old_next=
/mt/mt.cgi?__mode=rebuild&blog_id=1&type=Individual%2CMonthly%2CDaily%2CWeekly%2Cindex&next=2&offset=0&limit=&total=628&entry_id=&is_new=&old_status=&old_previous=&old_next=
こんな感じの出力が吐かれたら、たぶん成功。
ソース読めなくても、何をやっているか大体想像つくでしょ?
5. 最後にちょっとだけ。
さあ、実行できて再構築できたのだけど・・・。
ちょっとだけ気になることがあって、sixapart の中の人は何を考えたか、
my $build_type = 'Individual,Monthly,Daily,Weekly,index';
という、奇妙な build_type を指定しているのです。
まあ、これでもいいんだけど、Daily とか Weekly とか出力してない人には不要だし、ほかにも Page とか使ってる人もいそうだし。
あとは、Category とかもあるし・・・。
とりあえず、この部分は個人の好みで設定してあげてください。
一番最適なのは、MT の管理画面から再構築した時のアドレス部分の type をコピーすることです。
応用すれば、ブログ記事アーカイブだけとか、インデックスだけとかいった使い方もできます。
あとは、cron などに登録して、定期実行してあげるとか、使い方を工夫するとよいでしょう。
rebuild-pages をそのまま登録すると、毎日メールが送られてきて大変なので、エラー以外は /dev/null に出力を送ってあげることを忘れずに。


はじめまして techno さん。
MTでの再構築処理をcronを使って定期的に行いたく、色々と調べているところこのサイトに辿り着きました。
現在、指定日投稿の為にcrontabに以下のような設定↓
* * * * * cd /path/to/mt/; ./tools/run-periodic-tasks
(実際には時間を指定しており、正常に動作しています。)
をしていますが、同じように1日1回指定時にrebuild-pagesを使って再構築を行う設定も追加したいと思っております。
その場合の指定方法は、上記と同様に
* * * * * cd /path/to/mt/; ./tools/rebuild-pages MTログインのユーザ名 パスワード
のように、指定してあげればよいのでしょうか?
それとも他に正しい設定方法などがあるのでしょうか?
cronを使用しての実行は試されていないかもしれず、また、各サーバによる差分があるとも思いますが、大変申し訳ございませんが、もしご存知でしたらご教示いただけますようお願いいたします。
以上です、どうぞよろしくお願いいたします。
cron で再構築したいのであれば、それで大丈夫です。僕もそれで運用してます。
ただ、最後に書きましたがそのままでは、毎日 Cron Daemon からすごいメールが届くことになります。(やってみればわかりますが)
cd /path/to/mt/tools; time ./rebuild-pages user passwd > /dev/null
うちはこんな感じでやってます。
なんで、time なんか付けてるかというと、再構築にかかってる時間が毎日メールで送られてくるという、個人的な趣味というかなんというか。
返信いただき、本当にどうもありがとうございます。
アドバイスも参考にさせていただきます。
通りすがりのものですが、tools内のファイルを実行する際はmt.cgiがあるディレクトリから行うのが推奨されていると思います。そのようにやればLocal.pmを修正する必要は無いのでは?
コメントありがとうございます。
>tools内のファイルを実行する際はmt.cgiがあるディレクトリから行うのが推奨されていると思います
ソースがどこだかはわかりませんが、よく考えると、そうかもしれない...
試してみたわけではないですが、mt.cgi のディレクトリから実行すれば、問題ないような気がしますねー。
./$script_name|
の起点は、Local.pmのあるディレクトリではなくて、rebuild-pagesを実行したときのカレントディレクトです。
mt.cgiがあるディレクトリから、
./tools/rebuild-pagesと実行すればspawnの部分はエラーにはなりませんでした。