プログラム

Class: OPML Parser Class

PHP classes(http://www.phpclasses.org/)に最近登録されたOPMLパーサー。(http://www.phpclasses.org/browse/package/4026/)
アナウンスのメールを見ていたので試しに使ってみた。
このライブラリ以外に必須となるライブラリは無し。PHP標準関数を使って中で直でXMLを解析する様になっている。
使い方は非常にシンプル。

<?php
require_once('iam_opml_parser.php');
$parser = new IAM_OPML_Parser();
$parser->getFeeds("export.xml");  // export.xmlフィードリーダーが出力したOPML
print_r($parser->data);
?>

上のコードでわかる通り、パースするOPMLのソースを指定してgetFeedsというメソッドでOPMLが解釈されてインスタンスのメンバ変数に格納される。
上記のコードの実行結果は以下の通り。(メンバ変数dataのダンプ)

Array
(
[0] => Array
(
[names] => Subscriptions
[urls] =>
[targets] =>
[feeds] =>
[descriptions] =>
[created] =>
[type] =>
)
[1] => Array
(
[names] => にっき
[urls] => http://d.hatena.ne.jp/hideack/
[targets] =>
[feeds] => http://d.hatena.ne.jp/hideack/rss
[descriptions] =>
[created] =>
[type] => rss
)
[2] => Array
(
[names] => asahi.com
[urls] => http://www.asahi.com/
[targets] =>
[feeds] => http://feeds.asahi.com/asahi/TopHeadlines
[descriptions] =>
[created] =>
[type] => rss
)
)

直接、表示するためのHTMLを得たければdisplayOpmlContentsというメソッドがあるので、それを利用するとすぐにブラウザへ表示させることもできる様だ。

VCでDLLを作る話

DLLの中でMFCを使うと共有DLLでコンパイルしなきゃならないのか。(スタティックリンクにできない)
これに気づかず終日悩んでたのに、先ほど気づいたらあっという間に解決。
てか、以前つくったときには、ちゃんと意識していたんだろうけど時間が経っていたのですっかり忘れていた。
バラバラに作ってるので関連するプロジェクトは1つのソリューションファイルにまとめないとダメだ。と、今日の教訓。
うーん、始終VC++でプログラム書いてると、また違うんだろうけど、どうしても「にわか」状態になるところが悲しい。

勝手に回答するコーナー

id:its-tom の質問に勝手に回答するコーナー。
MySQLだとtimestamp型を使うとか。*1

CREATE TABLE TEST(
ID int,
CHECK_DATE timestamp
)

これで、

INSERT INTO TEST(ID) VALUES(0);

とすると、

ID=0
CHECK_DATE=20070709235540

と、いった感じにINSERT, UPDATEのタイミングで書き込まれる。
ただし、1テーブルに使えるtimestamp型は一つまで。

*1:もしかして、これは無しで、どうしてもDate型 etc... に入れたいって話だったのだろうか

KCAPTCHA + Ethna

EthnaKCAPTCHAを使うというお話。
KCAPTCHAは、よく会員登録サイト等である「ぐにゃ」っと曲がった文字列で画像認証するやつを作るためのPHPクラスライブラリ。PHP+GDで画像を作成してくれます。
例えば、

<img src="sample.php">

の様にして認証用画像を取得。sample.phpの中身はこんな感じ。

<?php
include('kcaptcha.php');
if(isset($_REQUEST[session_name()])){
session_start();
}
$captcha = new KCAPTCHA();
if($_REQUEST[session_name()]){
$_SESSION['captcha_keystring'] = $captcha->getKeyString();
}
?>

上のソースはサンプルのまま。
コンストラクタでヘッダ込みの画像データが吐かれるのでimgタグに画像が表示される。と。
表示の後、認証するためには画像に表示されている文字列を画面遷移後も保持しておく必要があるのでこのサンプルでは$_SESSION['captcha_keystring']に保持されているのだけど、ethnaの場合、Ethna_Sessionクラスでセッションが管理されるのでセッションIDが異なるので保持されない。
ということで、Ethnaのアクションクラスを作成

ethna add-action captcha

これで作成される app/action/Captcha.php の perform() 内に上記を真似て次の様な処理を書いておく。

<?php
include('kcaptcha.php');
//(中略)
function perform(){
if(!$this->session->isStart()){
$this->session->start();
}
$captcha = new KCAPTCHA();
$this->session->set("captcha_keystring", $captcha->getKeyString());
return 'captcha';
}
?>

これで、Smartyテンプレート内で

<img src="?action_captcha=true"><br>

何ぞと書けば無事表示。且つ、Ethna_Sessionにも表示した文字列が保持されているので、次のアクションでActionFormで取得した値とセッションの値とを比較すればよい。
なんと便利なライブラリだろう。作者の方に感謝。

…あとでキレイにまとめる。

ずっと愚直にサンプル通りやって、なんでうまくいかないんだろうと悩んでいたのだが、今朝バスに乗った瞬間、気づいたので駅までに着く間の10分でプログラムを書き上げた。
今日、一番集中力が出たのはあの時間だけだったかもしれない。

自作プログラムの話。

上は仕事のプログラムの話で次は自作のプログラムの話。
フィードリーダーを作って、あちこち手を入れつつ使っているのだけど巡回しているフィードの中で明らかに拒否反応的な内容を返してくるところがあることに気づいた。
巡回開始直後は希望するフィードのデータをくれていたのだけど、ある日を境にピッタリと中身が無くなり、広告しか入らなくなった。
これは、へんなbotか何かと解釈された。ってことなんでしょうか。
確かにヘッダとか今、特に書いていないので問題なのかなぁ。でも、巡回対象がフィードだからそんなに気にしなくてもいいと思っていたのだが。
実際に使い始めるといろいろなところが気になってくるものです。

System.out.printf(…)

上とは別にJavaのプログラムも書いているのだけど、そこで標準出力に文字列を出すときに1.5.0以降はSystem.out.printf("...");が使える様になったのを思い出して使ってみた。
うむ。ここだけは、やっぱりC言語みたくフォーマットを指定して書けるのがいいなぁ。
浮動小数点とかの出力を綺麗にしたいときに楽にできて非常にうれしい。
ただ、IBMJITコンパイラでは使えないのが残念。

time

%time php -q feedcrawle.php
0.727u 0.066s 0:50.45 1.5% 3841+6356k 0+1io 1pf+0w

実行してみて気づいた。
出力が微妙に違う気がする。上記は現在レンタルしてるサーバー(FreeBSD 6.1)のもの。
timeには…。

  • /usr/bin/time
  • csh, tcsh組み込みのもの

と2種類あるそうだ。*1
上記の場合、後者に該当して、

0.727u 0.066s 0:50.45 1.5% 3841+6356k 0+1io 1pf+0w

だと、

  • コマンド実行時間50秒45
  • ファイルI/O読み込み0回,書き込み1回

他はページやメモリだろうか。

*1:うーん、結構このコマンド何気に使っていたが気づかなかったなぁ

time2

書き忘れ。
上の記事で書こうとした本題はフィードの回収スクリプトが50秒もかかってます。というお話。
新規購読フィードが増えたから重かったのか、はたまた時間帯の問題なのか、それともこれが限界なのか?

比較表

結構、あちこちにありますが一応メモがてら。
変数(or 信号線)Aは4bit幅、Rubyの場合は%4bでフォーマットして表示させて、内部で処理させる符号は扱わないとしています。

操作内容 VHDL Ruby
ビット反転 not A (~a) & 0xf
2の補数 (not A) + '1' ((~a) + 1) & 0xf)
左1bitシフト A & '0' a << 1
右1bitシフト '0' & A(3 downto 1) a >> 1
LSBを0ビット目とした場合のxビット目 A(x) a[x]