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
ここ最近、iPhoneと同時に買ったiMacを常用しているのですがやっぱりスペースキーの右隣(かな)はEscapeじゃなきゃ嫌!ということでKeyRemap4MacBookを使いました。
以前からブックマークしていた紹介記事。
KeyRemap4MacBook最強過ぎる – antipop
このソフト、残念ながら「かな」をEscapeに変換する機能はついていません。あきらめていたのですが機能追加もやってみたら案外簡単でした。
公式のドキュメントを参照。
ソースをダウンロードして以下の2つのファイルを編集。
KeyRemap4MacBook-5.1.0/src/core/kext/remap.cpp
< void
2081,2088d2072
< remap_jis_kana2escape(const RemapParams ¶ms)
< {
< if (! config.remap_jis_kana2escape) return;
<
< RemapUtil::keyToKey(params, KeyCode::JIS_KANA, KeyCode::ESCAPE);
< }
<
< void
2700d2682
< remap_jis_kana2escape(params);
KeyRemap4MacBook-5.1.0/files/prefpane/checkbox.xml
1271,1274d1266
< <name>KANA to Esc</name>
< <sysctl>remap.jis_kana2escape</sysctl>
< </item>
< <item>
編集するファイル内にたくさんサンプルがあるのでコピペです。
ドキュメント通りにビルドして出来上がったpkgファイルを開いてインストール。
vim使いの中でもスペースの隣をEscにする人はあまり多くないようですが、、やはり快適。
ついでに「英数」で日本語入力のOn/Offを担えるようにしました。
同等の機能を持ったソフトでWindowsならKeyCtrl。
新機能盛りだくさんなのでちょっと試してみた。
PHP: doc:scratchpad:upgrade:53 [PHP Wiki]
ここに大まかな新機能は載っている。新機能としてnamespace, goto, closureが並んでいるのはPHPらしいと言うか何と言うか。
インストールは特に問題なし。Fedora5。
wget http://downloads.php.net/johannes/php-5.3.0alpha2.tar.bz2
tar jxvf php-5.3.0alpha2.tar.bz2
cd php-5.3.0alpha2
./configure
make
./sapi/cli/php -v
namespace、あると便利そう、と思っていたがクラスごとにuseを書くのは面倒でないか?
namespace Funaki::Test;
class Hoge { ... }
class Foo { ... }
こんな感じにクラスファイルを作っても(HogeとFooは別ファイルでもいい)呼び出すときに
use Funaki::Test;
$obj = new Hoge;
だけでは
Fatal error: Class 'Hoge' not found
が出る。use Funaki::Test::Hoge; と書く必要があるようだ。::の前に$hogeと変数は使えないのでuseよりフルネームで書くことの方が多そう。
closureは、、使うだろうか。
?:も
$hoge = (isset($array['idx']) ? $array['idx'] : null);
を
$hoge = ($array['idx'] ?: null);
と書けるならよかったのだが、idxがないとNotice: Undefined offsetエラーが出るので使う機会はないと思う。
__DIR__は地味に便利だ。dirname(__FILE__)のエイリアス。
NEWDOCやDateTimeとかPharも使う機会はありそう。gotoも使ってしまうかもしれない。
vimのsyntax highlightがまだ対応していないのでちょっと寂しい。
この辺も気になる。
PHPTypeSafeで目から鱗が落ちた – Do You PHP はてな
本を読む PHPカンファレンス2008に参加しました
mysqlndで速くなったらしい。
PHP本体も
php.internals: Re: re2c scanner issue
パーサーをre2cなるものに変えて速くなったらしい。メモリ効率の改善はうれしい。
CentOSのyumで入れられるようになるのはいつかなー。