2004年10月29日

Phidget

Phidgets
Phidgets Inc. :: Unique USB Interfaces

F氏に教えてもらった、USB経由でいろんなデバイスをアレコレするもの。

いろいろできそうです。

結構安い。
サーボなんて18カナダドル(っていくら?)。

オフィシャルではないけどOS Xのフレームワークもある。でもC++かー。

2004年10月25日

リビルド終了を待たずにコメント動作を完了

Movable Typeでコメントを書き込むと、リビルド動作を伴うので終了までずいぶん待たされることがある。

jm@foo: コメント時のリビルドではお知らせメール機能を利用してインデックスのリビルドを非同期で行う方法を試したが、アーカイブの種類が多かったりするとこのやりかたでもまだまだ遅い。そこで以下の改造をしてみた。

jm@foo: コメント時のリビルドにも書いている、forkする方法。要するに、同期してリビルドしなければならないIndividual Entryアーカイブ以外は子プロセスとして裏でゆっくりリビルドしてもらい、親のプロセスはさっさと終了する。

lib/MT/App/Comments.pmの190行目、

$comment->save; $app->rebuild_entry( Entry => $entry )
$comment->save; my $pid = fork(); if (!$pid) { close STDOUT; $app->rebuild_indexes( Blog => $blog ) or return $app->error($app->translate( "Rebuild failed: [_1]", $app->errstr)); exit; } $app->rebuild_entry( Entry => $entry )
に変更。さらに lib/MT.pmの196行目
return 1 if $blog->is_dynamic; my $at = $blog->archive_type; if ($at && $at ne 'None') { my @at = split /,/, $at; for my $at (@at) { if ($at eq 'Category') { my $cats = $entry->categories; for my $cat (@$cats) { $mt->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => $at, Category => $cat, ) or return; } } else { $mt->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => $at ) or return; } } }
return 1 if $blog->is_dynamic; $mt->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => 'Individual' ) or return; my $pid = fork(); if (!$pid) { close STDOUT; my $at = $blog->archive_type; if ($at && $at ne 'None') { my @at = split /,/, $at; for my $at (@at) { if ($at eq 'Category') { my $cats = $entry->categories; for my $cat (@$cats) { $mt->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => $at, Category => $cat, ) or return; } } elsif ($at eq 'Individual') { } else { $mt->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => $at ) or return; } } } exit; }
に変更。 でもMTの3.1ではリビルドを非同期で行うか否かの設定もできるようになっているみたいなので、バージョンアップするのが一番いいかも。

2004年10月20日

ecto 2.0.4

ecto 2.0.4

しばらく前にレジストしていたのだが、EUCはHTML Entityでエンコードしないと化ける、という情報を読んで、それじゃあなあ、と使わずにいた。
しかし今日ふと、最近のMovable Typeの日本語化パッチはXMLRPCをUTF-8に統一していることを思いだし、ectoもXMLRPCを使っているんだろうからエンコードなしでも化けないのではないかと試してみた。

…化けなかった。

2004年10月15日

いくらなんでも

こりゃないんじゃないの?

pb.jpg

まねっこの方は何もかもがすべてダサいのがある意味すごい。
Appleのデスクトップ画像のデザインって、誰だっけ?

卸町まちづくりプロジェクト展

卸町まちづくりプロジェクト展

なんで最近Movable Typeばっかりいじっているかというと、上記のプロジェクトの一部でバーチャル卸町ブログというのを作っているからなのだった。個人サイトじゃないので、いろいろ細かいところを詰めて使い勝手を上げておかないと、と。MTを詳しく調べるいい機会になったような、使いみちのないノウハウを溜めてしまっているような…

ULSEからの技術提供。以前から地域限定ULSEを一度やってみたいと思っていたので、楽しみです。
あー現地から投稿したい。

2004年10月14日

エントリー保存時にインデックスをリビルドしない

前のエントリーに引き続き、次々エントリーを編集したいときの話。
次々エントリーを編集していくときは、一つ保存するたびにいちいちインデックスをリビルドされると時間とCPUの無駄。なのでリビルド権限のないユーザーを作って試してみたが、エントリー保存の際は権限がなくてもリビルドしてしまう。そこでlib/MT.pmを読んでみると、コード中のコメントに、エントリの依存関係を考慮するのは大変だから前後のエントリーとインデックスは決め打ちでまとめてリビルドしちゃうよーんとか書いてある。一応 BuildDependencies というフラグがあるので、これを利用して他のファイルをリビルドしないように変更する。

lib/MT/App/CMS.pm 2320行目

$app->rebuild_entry( Entry => $entry, BuildDependencies => 1 ) or return;
if ($perms->can_rebuild) { $app->rebuild_entry( Entry => $entry, BuildDependencies => 1 ) or return; } else { $app->rebuild_entry( Entry => $entry, BuildDependencies => 0 ) or return; }
に変更。

これでリビルド権限のないユーザーで入って編集しているときはエントリー自身以外のファイルはリビルドされなくなった。リビルドしたいときは権限を持ったユーザーで入り直してリビルドする。

追記
しかし考えてみるとエントリー自身のリビルドも無駄。エントリーのタイトルなどを変更した場合はIndividual Archiveをまとめてリビルドしないと前後のエントリーの<MTEntryPrevious>や<MTEntryNext>に表示されるタイトルが古いままになってしまう。Individual Archiveをまとめてリビルドすれば編集したエントリー自身も当然リビルドされるので、二重にリビルドすることになる。

そもそも権限がなくてもリビルドされるようになっているのは、そうじゃないと普通は不便だからだが、ここにあげているような状況の場合は逆に厳密に権限に従うのが理に適っている。
というわけで結局上記の変更は破棄して以下のようにした。

lib/MT/App/CMS.pm 1747行目

if ($obj->status == MT::Entry::RELEASE() || $status_old eq MT::Entry::RELEASE()) {
if ( ($obj->status == MT::Entry::RELEASE() || $status_old eq MT::Entry::RELEASE() ) && $perms->can_rebuild) {
に変更。

エントリー編集画面内にプレビュー表示

大量のエントリーを次々に編集するときなど、プレビューを見ながら作業したいことがある。
そこで以下のようにしてみた。

lib/MT/App/CMS.pm 509行目

$param{can_view_log} = $app->{author}->can_view_log; } elsif ($type eq 'category') {
$param{can_view_log} = $app->{author}->can_view_log; require MT::Builder; require MT::Template::Context; require MT::Blog; my $blog = MT::Blog->load($blog_id); my $ctx = MT::Template::Context->new; $ctx->stash('entry', $obj); $ctx->stash('blog', $blog); my $build = MT::Builder->new; my $preview_code = <<'HTML'; <p><b><$MTEntryTitle$></b></p> <$MTEntryBody$> <$MTEntryMore$> HTML my $tokens = $build->compile($ctx, $preview_code) or return $app->error($app->translate( "Parse error: [_1]", $build->errstr)); defined(my $html = $build->build($ctx, $tokens)) or return $app->error($app->translate( "Build error: [_1]", $build->errstr)); $param{preview_body} = $html; } elsif ($type eq 'category') {
に変更。そして tmpl/cms/edit_entry.tmpl の好きなところに<TMPL_VAR NAME=PREVIEW_BODY>を追加。つまりEntry編集画面のテンプレートにプレビュー画面と同じ変数が渡るようにして、それを表示するようにした。

コメントスパム対策その2

しばらくログを取ってみたら、スパムの多くがRefererを送って来ていないようなので、jm@foo: コメントスパム対策に加えて、以下のようにしてみた。

lib/MT/App/Comments.pm 161-162行目の

} my $comment = MT::Comment->new;
} require MT::ConfigMgr; my $cfg = MT::ConfigMgr->instance; my $archive_url = $blog->archive_url; my $comment_cgi = $cfg->CGIPath . 'mt-comments.cgi'; my $refer = $ENV{'HTTP_REFERER'} || 'No referer'; unless ($refer =~ /^($archive_url|$comment_cgi)/) { $app->log("Invalid referer ($refer), $user_ip"); return $app->handle_error('リファラ(<a target="_blank" href="http://service1.symantec.com/SUPPORT/INTER/nisjapanesekb.nsf/jp_docid/20031024163125947?Open&src=&docid=20021020160209947&nsf=support%5CINTER%5Cnisjapanesekb.nsf&view=jp_docid&dtype=&prod=&ver=&osv=&osv_lvl=">参考</a>)が無効です'); } my $comment = MT::Comment->new;
に変更。こちらはベイジアンフィルタの場合と違い、コメントを保存する前に弾いている。 はじめ、
return $app->handle_error($app->translate('Invalid referer'));
として、ja.pmを使って日本語メッセージを表示しようと思ったのだが、なぜか日本語に変換されないので、コード中に直書き。そういえば'Name and email address are required. 'も日本語化されていない。なぜだろう?

2004年10月13日

Tokyo Art Beat

Tokyo Art Beat - 東京のアート/デザイン増幅器

REALTOKYOとどっちが使いやすいかな。
TDBの情報を結構うまく整理しているところなど、期待大。

なんとなくピンと来るものがあってたどってみたら、やっぱり主催者の一人は
http://hotwired.goo.ne.jp/news/culture/story/20040415204.html
に登場するバロン氏だった。たぶん。

ていうかTDB本家の情報デザインがひどすぎ。
Webにしろ会場で配っていたブックにしろ、ある程度状況を把握している人にはすごく便利、というものになっている。はっきり言えばスタッフや関係者のための情報ツールにしかなっていない。ほとんどの客にとってはアーティスト名のインデックスや検索なんか意味ないんだよ。知らないアーティストに出会いたいんだし、人間はインデックスから時空間をワープできるわけじゃないんだからさ。
事後の記録としてはこれでもいいけど、ギャラリーや美術館の中じゃなくて現実の都市の中に散らばってイベントが起きているというダイナミックさを理解していない、もしくは重要視していない構成であるとは言えるな。

その点、エリアごとに情報をまとめたTokyo Art Beatは正しい。生身の人間は地理・空間をたどって歩くのだ。

2004年10月02日

携帯電話でWebブラウズ

いまどき、大抵の携帯電話がWebブラウズ機能を持っているが、かなり使い勝手が悪い。

IMG_6031.jpg htmlのサイズがたかだか数キロバイトを超えただけで表示不可能になる。画像ファイルも大きなものは全然ダメ。

IMG_6033.jpg 携帯用に縮小して中継してくれるキャリアもあるが、1ページに複数の画像があるとすぐにギブアップ。そして遅い。
フレームが切ってあるページに至ってはもう完全にお手上げ。事実上携帯用に作成されているページしか見られないに等しい。最近H"などに搭載されているいわゆるフルブラウザも、大きなデータは結局「メモリ不足」で表示できないようだ。

PCから普通にブラウザで見られるものが、携帯からだと全然ダメ。携帯が膨大な情報源から切り離され、プロプライエタリかつショボい有料コンテンツだけの小さな世界に閉じこめられた状況がもうずっと続いている。

Googleには携帯向けの検索画面とそこからリンクされるコンテンツ変換サーバがあるので、検索画面を経由する限りネット上のどのページでも見ることが出来る。これを使えば上記の狭い世界から外へと踏み出せる。しかし、検索結果の件数は少なく要約もほんのちょっとしか表示されないし、変換されたリンク先のページでは画像が表示されない。1ページあたりのテキスト量も一昔前の携帯電話のレベルに抑えられているので、目的の情報を得ようとすると何度もページ送りをするハメになることが多い。狭い世界から外へ出ることはできるが、かなりの足枷つきという感じ。

なので、町を歩きながら気になったものをその場で調べようとすると、かなりもどかしい思いをすることになる。普通にGoogleで検索結果の一覧をざっと見て、必要であればそれぞれのページに飛んで内容を読む。さらに必要であれば画像も見る。たったこれだけのことが、できない。携帯電話の限定されたインターフェイスを使う以上、あまり多くを望んでもバランスが悪いとは思うが、せめて好きなように外を歩き回るくらいはできないものか。

そこで、

IMG_6030.jpg
・携帯電話のブラウザにとってあまり意味のないタグなどを削除し、htmlをダイエット
・それでもあふれる分はページ分割表示

IMG_6038.jpgIMG_6041.jpgIMG_6043.jpgIMG_6044.jpgIMG_6047.jpg
・画像はリンクとして表示、クリックすると携帯電話に合せて縮小表示、任意の領域を拡大表示可能

という動作を行うProxyサーバのフィルタを作った。

これでほとんどのページが閲覧可能になった。 IMG_6027.jpgGoogleも携帯用のそれではなく一般のブラウザと同じ情報量の結果表示が可能。

ただし、情報伝達をレイアウトに依存しているようなページ、フルFlashでテキストページが用意されていないものなど、アクセシブルでないページはどうしようもない。
また、入力フォームはうまく動けばラッキー、くらいのものになっている。ページ分割が<form>&lt/form>タグの内側で行われた場合はフォーム自体動作しないし、フィルタで文字コードを変換しているため、受け側のCGIの作りが雑だと送信したテキストが思いきり文字化けすることになる。

このシステム、個人的にもう数年間使っているが、上記の制限を受け入れている限り、特に困るようなこともない。しかし、どこでも携帯を見つめて検索しまくってしまうので、周囲にウンザリされるという欠点はある。

これ、需要はありますかね?

Webカメラ

先日終了したCET04ことセントラルイースト東京2004。
期間中、インフォメーションセンターの二ケ所にWebカメラを設置した。事務局のコアでもあるREN-BASE UK01と、期間限定バーを兼ねていたUntitled。
cetcams.jpg

それほど長い期間ではないので、全画像を記録してしまうことにして、それらをブラウズするシステムも同時に作成。基本的にRENは30秒、Untitledは15秒間隔で画像を取得している。(RENでカメラを接続していたマシンは専用ではなかったため、ときどきWebcamソフトが落ち、画像がフリーズしている)

ただの静止画のWebカメラなのだが、過去にさかのぼれるだけで相当おもしろくなる。

rencam.jpg
REN-BASE UK01
シンポジウムなどが頻繁に行われていたので、その前後で大幅にレイアウトが変わる様子や、深夜にわたるスタッフたちの動きが記録されている。

utcam.jpg
UNTITLED BAR
こちらも多くの人が入れ替わり立ち替わり現れては去っていく様子がわかる。時には2時3時まで飲む人たちの姿も。そしてこちらにも世間一般から見ると少し異常な時間に日常的に働く人の姿が写っている。

CETに関わった多くの皆さん、本当にお疲れさまでした。

ところで、期間中カメラとそのシステムのことをずっと気にかけていたら、その気がかりが勢い余って(?)、自宅で寝ているときに夢うつつで自室にもカメラが設置してあるような錯覚に襲われてしまい、寝相を気にしたりして非常に寝苦しかった(笑)。