ロリポップがサーバを強化したりPHP5が導入されたりで月200いくらにしてはいいことも多いのだが、.htaccess の設定が変わって動かなくなったり、このブログも文字化けたり (wordpress も3に上げたので原因は定かではないが) で嫌気が差したので管理が楽な Rackspace Cloud へ移行。*.zuzara.com の全コンテンツを移行したいところだが、ひとまず blog.zuzara.com から。
文字化けの原因はわからなかったが、新しい phpMyAdmin から wp_ のテーブルをダンプした限りでは文字化けなしの UTF8 でダウンロードできた。wordpress.org からソースをダウンロードして、まっさらなデータベースにインストールした後、wp-content のファイル群をコピーして、コマンドラインから wp_ の前のデータを INSERT。ダンプ時に DROP TABLE を入れておく。
ちなみにロリポップの管理画面に Firefox と Google Chrome からログインできないようだ。Safari5 で入れた。
もともと車の運転には嫌な思い出が多く、できることなら運転などしたくないのだがいかんせん借りたオフィスが自宅から自転車とバスと電車で1時間半かかり、車だと15分なのでやむを得ず。中古車を買おうと決めたものの、Civicって何?というレベルだったので時間がかかった。El Camino沿いにあるホンダのディーラーに、フランク高田氏という感じの良い方がいて電話したり何度か訪れた。最終的には安い方を優先して Stanford から日本に帰る方から購入。
- 日本車、特にトヨタ、ホンダは高い
- 燃費は年数よりエンジンの大きさに左右される
- $3,000代の日本車はディーラーには置いてない
- 相場は kbb.com で調べる
- VIN から無料でわかる情報は少ない
- craigslist から探すのは信用度の問題で時間がかかる
- 個人売買で日本人から買うなら、Stanford のML (転送していただいた)、ベイスポ、ミツワの張り紙などから情報収集
- 直感的に、帰国する人から買うのが一番信用できる
- 見てもわからないが、見に行かないと交渉が進まないので現所有者は自宅から近い方がいい (Berkley は遠すぎた)
- 3月下旬、Santa Clara のDMVで筆記試験を日本語で受ける
- 筆記試験は、日本語の過去問を知人からいただいたので軽く予習して問題無し。むしろ試験に出ないが知っておいた方がいいルールが結構あるように思う。
- 車の保険は日本語のわかるエージェントを通して、AAAのプレミアメンバーにはサイトから加入
- 3月の末に 11k miles の ’98 Honda Civic を $3,300 で購入 (GPS, Repair Shopでの点検, Carfaxの所有者履歴込み)
- 10日後に自宅でエンジンがかからずレッカーされ修理費 $640
- DMV の面接予約サイトからは ID が不正だと怒られ、いくら電話しても全く出ず諦めて DMV まで赴き実地試験の予約を取る。1ヶ月後。
- 慣れたかな、と思ったときに駐車場でアクセルを踏みすぎ左のライトを木にぶつけレッカー。$2,400 請求されるも友人に紹介してもらった工場で $1,400 で修理してもらう。自損の保険に無加入だったので全額負担。
- DMV で実地試験。道が広く単純だし、練習期間は十分長かったので余裕だった。1週間ほどで免許証が送付されてきた。ようやくパスポート無しでお酒が買える。
- サンクリップ、というよりでかいサングラスをウォルマートで$20で購入。メガネの上からかけられる。ファッション性に欠けるが、安かったし便利。
- Mountain View にもDMVはあるが商用のみ
- Santa ClaraのDMVは常に長蛇の列。アポを取ったはずの実地も30分は待たされた。
- 日本の免許と筆記試験後にもらう仮免許があれば1人で運転可
ぶつけたときは本当に誰も怪我しなくてよかったが、$2,400 も請求されてちょっと人間不信に。次に行ったところは $1,800。友人に紹介してもらったところは $1,400。ここはベトナム系なのだが、友人もいたし値段も落ち着いたせいもあるだろうが、同じ英語に不自由を感じるアジア系として激しい親近感を覚えた。
stripos を使っているPHPのコードをロリポサーバにアップしたら undefined function エラーが出た。実は PHP5 以降の関数であることに気付き、PHP5に移行することにした。ユーザの管理画面から移行、とやればすぐ終わる。実際に移行が完了するまでに1〜2時間ぐらいかかった。
問題ないといいなぁ、と思ったが今のところ1つ問題発生。pukiwiki が動かなくなった。ロリポの PHP5 は CGI で動いていて group名は LolipopUser として動いている。今までは apache ユーザだったので生成されたファイルの権限が違って書き込もうとすると runtime error が出る。ざっと調べた限り、ロリポとしては対策を立てていないようなのであきらめて全部ダウンロードしてアップロードし直した。やれやれ。
Cookpad が上場するという話を TechCrunch で読んで、何となく気になったのでちょっと調べてみた。ここでいうネット系というのはウェブサイトを中心にビジネスをしていそうな企業。例によって携帯からのアクセスが反映されないとかドメイン1つでは足りていないとか数字には問題がありそうだが参考にはなりそう。
トラフィックの多い順に、
- mixi.jp
- itmedia.co.jp
- carview.co.jp
- cookpad.com
- coneco.net
- homes.co.jp
- zozo.jp
- gree.jp
- naturum.co.jp
- ec-current.com
- magaseek.com
- carenet.com
Google Trends for Websites: mixi.jp, itmedia.co.jp, carview.co.jp, cookpad.com,
Google Trends for Websites: gree.jp, cookpad.com, coneco.net, homes.co.jp, zozo.jp,
Google Trends for Websites: gree.jp, ec-current.com, magaseek.com, naturum.co.jp, carenet.com
Google Trends がサイト5つまでしか表示してくれないので分割してある。mixi が飛び抜けていて cookpad と coneco 以下にも大きな開きがある。
それぞれのサイトの内容は分かれていて、あまりかぶっていない。
このグラフを信じるならこの2年間でトラフィックはどこもあまり増えていない。 mixi は特に右肩下がりで、上がっているサイトはない。携帯に移行しているにしてもちょっと意外。
以下は上場した日付と社名。
12/17/08 グリー
08/07/08 ベンチャーリパブリック
12/11/07 スタートトゥデイ
10/19/07 ナチュラム
06/12/07 カービュー
04/20/07 ケアネット
04/19/07 アイティメディア
02/20/07 ストリーム
11/28/06 マガシーク
10/31/06 ネクスト
09/14/06 ミクシィ

Mac の Dashboard の WebClip で Google の “dollar yen” の検索結果を切り抜くだけ。1ドル何円か、わかります。Dashboard を開くたびに更新されるようです。
折れ線グラフも欲しい場合はこちらが便利です。
アップル – ダウンロード – Dashboard ウィジェット – Yen Exchange Rate
久々に変えてみた。自作はやめてこちらに。
Fusion « Digital Nature
トップページに記事本文を表示せずにタイトルだけ列挙するように index.php と style.css をちょっといじった。
ボナンザはWindowsで動くコンピューター将棋ですが、Mac でも動いて欲しかったので Wine を入れてみました。Mac OS X 10.5.5、Bonanza は 4.0.4 です。

最初、dmg で配布されている1.1.7をインストールしたのですがexeを実行すると、mfc42.dll がないと怒られ、ダウンロードして再度実行すると今度は “gdi32.dll” failed to initialize, aborting となる。これはbonanzaに限らないのでこのdmg自体に問題がある模様。
あきらめて一度アンインストール(ページ下部参照)して、ports から改めてインストール。少し時間がかかる。
% sudo port install wine
% sudo port install winetricks
% winetricks vcrun6
% wine Csa.exe
これで無事起動。
いや、しかし勝てない。1年前と違い、序盤も最新型で組んでくるのが小憎らしい。
お蔵入りしていたコード。
PDFを検索したときの結果には画像でスニペットを返した方が見やすいかも、というアイディアを実現しようとしたもの。なぜ画像の方がいいかというと検索語近辺のテキストをスニペットにしても、表だったりPDFの中で文字列が表示される順に記述されていなかったときに脈絡がなくて役に立たないことがあるから。
さて、デモコードはまずユーザからURLで指定されたPDFファイルをサーバでダウンロード、テキストを抽出する。テキストにはPDF上での位置情報が付与されているので、それを含めてJSON形式でJavaScriptのコードに直接出力。文字列の検索はJavaScriptでやって、ハイライトは先の位置情報から画像の上にCSSで乗せる。
現状では、重い、PNGへの変換精度がいまいち、検索の機能が貧弱、等々実用化するまでには問題がたくさんある。
PDFからテキストを抽出、PNGに変換するところにはいくつか既存のアプリを使っている。
<?php
require_once 'Zend/Uri.php';
define('PDF_SAVE_PATH', '/tmp/pdfsearch/');
define('PNG_SAVE_PATH', '/var/www/zuzara.org/pdfsearch/png/');
dl('json.so');
$errorMessage = '';
$pdfUrl = (isset($_GET['pdfurl']) ? $_GET['pdfurl'] : '');
$seed = '';
$images = array();
$data = array();
if ($pdfUrl != '') {
try {
$uri = Zend_Uri::factory($pdfUrl);
if ($uri->valid() === true) {
$seed = md5($pdfUrl);
$pdfFile = PDF_SAVE_PATH . $seed . '.pdf';
$txtFile = PDF_SAVE_PATH . "$seed.txt";
if (!file_exists($pdfFile)) {
`wget -q -O $pdfFile "$pdfUrl"`;
`pdftoppm -f 1 -l 1 $pdfFile $pdfFile`;
`mogrify -format png $pdfFile-*`;
$cmd = "$pdfFile-*.png " . PNG_SAVE_PATH;
`mv $cmd`;
`/usr/local/src/xpdf-3.02/xpdf/pdftotext $pdfFile -f 1 -l 1 -cfg /etc/xpdfrc -layout -enc UTF-8 >$txtFile`;
$buf = file_get_contents($txtFile);
$frags = explode('*** line fragments ***', $buf);
foreach ($frags as $i => $frag) {
$d = preg_match_all('@x=([\d\.]+)\.\.([\d\.]+) y=([\d\.]+)\.\.([\d\.]+) base=[\d\.]+ \', text: (.*?)\'@s', $frag, $m);
$data[$i] = array();
for ($j = 0; $j < $d; $j++) {
//$data[$i][] = array('text' => $m[5][$j], 'xMin' => $m[1][$j], 'xMax' => $m[2][$j], 'yMin' => $m[3][$j], 'yMax' => $m[4][$j], );
for ($k = 1; $k <= 4; $k++) {
$m[$k][$j] = intval($m[$k][$j]) * 2.084;
}
$data[$i][] = array('text' => $m[5][$j], 'top' => $m[3][$j], 'left' => $m[1][$j], 'width' => $m[2][$j] - $m[1][$j], 'height' => $m[4][$j] - $m[3][$j], );
}
}
file_put_contents($txtFile, serialize($data));
} else {
$data = unserialize(file_get_contents($txtFile));
}
foreach (new DirectoryIterator(PNG_SAVE_PATH) as $file) {
if (strpos($file->getFilename(), $seed) !== false) {
$images[] = $file->getFilename();
}
}
sort($images);
} else {
$pdfUrl = '';
}
} catch (Zend_Uri_Exception $e) {
$errorMessage = $e->getMessage();
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>pdfsearch</title>
<script type="text/javascript" src="jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="jquery.dimensions.js"></script>
<script type="text/javascript">
data = <?php echo json_encode($data); ?>;
$(function() {
$('#searchbox').submit(function() {
var query = $(':text').val();
var matched = 0;
jQuery.each(data, function(i) {
jQuery.each(data[i], function(j) {
if (data[i][j].text.match(query)) {
var t = $('#p-0').position().top + data[i][j].top;
$('#highlight').css({ top: t,
left: ($('#p-0').position().left + data[i][j].left),
width: data[i][j].width,
height: data[i][j].height,
});
$(window).scrollTop(t - 50);
$('#highlight').show('fast');
matched++;
return;
}
}
);
}
);
if (matched == 0) {
alert("did not match.");
}
return false;
});
});
</script>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>
<body>
<h1>pdfsearch</h1>
<?php if ($errorMessage != ''): ?>
<div id="errormessage"><?php echo $errorMessage; ?></div>
<?php endif; ?>
<?php if (count($images) > 0): ?>
<form id="searchbox" action="" method="GET">
<input type="text" name="search" />
<input type="submit" value="submit" />
</form>
<?php endif; ?>
<?php foreach ($images as $p => $image): ?>
<h2>page: <?php echo $p+1; ?></h2>
<img id="p-<?php echo $p; ?>" src="png/<?php echo $image; ?>" alt="" />
<?php break; /*XXX*/ endforeach; ?>
<form id="submitpdfurl" action="" method="GET">
pdf url:
<input type="text" id="pdfurl" name="pdfurl" value="<?php echo htmlspecialchars($pdfUrl, ENT_QUOTES); ?>" />
<input type="submit" value="Convert!" />
</form>
<div id="highlight"></div>
</body>
</html>
紙copi のデータを PukiWiki に移行しようと思って適当なスクリプトを書いた。
wiki フォーマットで書いていないので見た目は乱れるがMacを使うことが多くなったのでPukiWiki一本にまとめることにした。
<?php
/**
* PukiWiki HTTP API
*
* @since 2009.1.18
*/
require_once 'Zend/Http/Client.php';
class Pukiwiki_API
{
const DEFAULT_ENCODING = 'EUC-JP';
private $_http;
public function __construct($serverName, $httpAuthUserName, $httpAuthPassword)
{
$this->_http = new Zend_Http_Client($serverName, array('keepalive' => true));
$this->_http->setAuth($httpAuthUserName, $httpAuthPassword);
}
public function write($title, $body)
{
$this->_http->setParameterPost(array(
'encode_hint' => $this->encode('ぷ'),
'template_page' => '',
'cmd' => 'edit',
'page' => $this->encode($title),
'digest' => md5(''),
'msg' => $this->encode($body),
'write' => $this->encode('ページの更新'),
'notimestamp' => 'true', // 効いてる??
'original' => $this->encode($body),
));
$response = $this->_http->request('POST');
//echo mb_convert_encoding($response->getBody(), 'UTF-8', self::DEFAULT_ENCODING);
}
private function encode($str)
{
return mb_convert_encoding($str, self::DEFAULT_ENCODING, 'UTF-8');
}
}
呼び出し側は
<?php
require_once 'Pukiwiki_API.php';
$p = new Pukiwiki_API('http://PukiWikiを設置したサーバ/', 'ベーシック認証用のユーザ名', $argv[1]);
$path = realpath($argv[2]); // 紙copi のディレクトリを指定
$pathLen = strlen($path);
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object) {
if ($object->isFile()) {
$pageName = "kami" . substr($name, $pathLen);
$body = mb_convert_encoding(file_get_contents($name), 'UTF-8', 'SJIS');
echo $pageName, "\n";
$p->write($pageName, $body);
}
}
先月からムームードメインがようやくDNSをいじれるようになった。大歓迎。
で、全部無料なのが怖いぐらいGoogleに依存しているのでGoogle Appsを使うことにした。
ムームーDNS:カスタム設定でレコード情報を変更 – NEO-SHOCKER.COM
ここに書いてある内容で網羅されているが一応設定を書いておくと、
MX ASPMX.L.GOOGLE.COM 10
MX ALT1.ASPMX.L.GOOGLE.COM 20
MX ALT2.ASPMX.L.GOOGLE.COM 20
MX ASPMX2.GOOGLEMAIL.COM 30
MX ASPMX3.GOOGLEMAIL.COM 30
MX ASPMX4.GOOGLEMAIL.COM 30
MX ASPMX5.GOOGLEMAIL.COM 30
TXT v=spf1 include:aspmx.googlemail.com ~all
mail CNAME ghs.google.com
etc...
最後に、ネームサーバをムームDNSに変更して設定完了です。
この部分を抜かしていてハマった。。48hを過ぎてもAppsはいっこうに使えるようにならず。。
ムームードメイン – ネームサーバ設定変更
このページで「ムームードメインのネームサーバ(ムームーDNS)を使用する 」にチェックを入れて更新すればOK。僕の場合は、カスタム設定をしたつもりがここのチェックがロリポップのままで反映されていなかった模様。
設定後、しばらく待てば反映される。
CNAMEが設定されているかのチェックは
Creating CNAME records – Google Apps for Administrators
ここの「Check the status of your CNAME record」でできる。
GmailのLab機能がGoogle Appsのメールでは使えないようで、ちょっと不便になった。
labelやfilterをエクスポートしてインポートしたいがそれはできないようだ。
iPhoneのiCalとGoogle Calendarの同期にNuevaSyncを使っている。こちらも移行しないといけない。
追記:
Appsのカレンダーの同期も簡単になった。
Apps専用の設定でOnにしてから後は普通のGoogle Calendarと同じ。
Google Sync via ActiveSync – Google Apps Help
参考:
格安サーバ・ロリポップを使い倒す « zuzara