はてなダイアリーの注目商品から商品を選ぶと、表示されるページの下に商品を含む日記のリンク先があります。そのリンク先をすべて一度にブラウザで表示できるプログラムあると便利かなと思って作ってみました。

最初は WebKit を利用してリンク先を抽出するプログラムを作成しようとしたのですが、簡単にできそうではありませんでした。そこでブラウザ上に表示されたリンク先をすべてドラッグして選択し、クリップボードにコピーした後、クリップボードからリンク先を抽出するようにしました。拙作 StripToString の一部を利用しました。その過程で StripToString のバグを見つけてしまったのですが、使っている人もいないと思うので、修正版を公開するか悩んでいます。

また RSSファイルも読み込めるようにしました。RSSファイルを表示するプログラムは、本格的なものを作ろうとすると大変かもしれませんが、Cocoa バインディング、キー・バリュー・コーディング、NSXMLDocument、XPath を理解していれば簡単に作成できます。ぜひチャレンジしてみてください。

あとRSSファイルを直接ダウンロードしたいときは、ターミナルで curl コマンドを使うと便利だと思います。下の例が、’はてなブックマーク最近の人気エントリー‘ を hatena.xml というファイル名でダウンロードする例です。

curl "http://b.hatena.ne.jp/hotentry?mode=rss" > hatena.xml

実行ファイル名 OpenURLHatenaRSS でわかるように、最初は ‘はてな’ だけに対応していたのですが、いろいろなソーシャルブックマークを表示するようにしてみました。

RSSファイルの URL をポップアップメニューで表示するようになっていますが、自分でカスタマイズしたくなると思います。その時は実行ファイル OpenURLHatenaRSS を Finder の ‘パッケージの内容を表示’ を選んで Contents/Resources/Japanese.lproj/Localizable.strings ファイルを変更してください。ファイルの文字コードUTF-16 なので注意してください。

"RSS_TITLE19"="ニフティクリップ - 最新クリップ";
"RSS_URL19"="http://clip.nifty.com/feeds/rss/recent";
"RSS_TITLE20"="ニフティクリップ - 人気クリップ";
"RSS_URL20"="http://clip.nifty.com/feeds/rss/popular";

RSS_TITLE数字’ がメニューに表示されるタイトル、’RSS_URL数字’ がRSSファイルの URL です。RSS_TITLE00、RSS_URL00 は表示されません。また、’RSS_TITLE数字’ が文字 ‘-‘ の時は区切りが表示されます。詳しくはソースを参照してください。数字は1から最大100までです。表示したいメニューの数字まで連続していないとメニューが途切れてしまうので注意してください。

PeanutsView

プログラムの動作は単純です。簡単に説明すると、フレームのサイズをゼロにした WebView を作成し、 http://snoopy.com/ からデータを読み込みます。mainFrame から DOMDocument を取り出し、DOMHTMLDocument に変換、そこから images メソッドを使って画像をリンクしている DOMNode ( DOMElement ) を集めた DOMCollection を取り出します。

後は DOMCollection から DOMNode を順番に取り出し、DOMElement に変換、getAttribute:@”SRC” を呼び出し、取り出した attribute の文字列と @”/comics/peanuts/archive/images/peanuts” で始まる文字列を比較し、一致した場合 src に格納します。後は URL を作成し、NSImage を使って画像を Web から取り出して表示します。

下記はソースから重要な箇所を抜粋したものです。詳細はソースを参照してください。

 _webView = [[WebView alloc] initWithFrame:NSZeroRect];
[_webView setFrameLoadDelegate:self];
frame = [_webView mainFrame];
url = [NSURL URLWithString:@"http://snoopy.com/"];
request = [NSURLRequest requestWithURL:url];
[frame loadRequest:request];
frame = [_webView mainFrame];
htmlDocument = (DOMHTMLDocument *)[ frame DOMDocument ];
collection = [htmlDocument images];
for (i=0; i<[collection length]; i++) {
element = (DOMElement *)[collection item:i];
if ([[element getAttribute:@"SRC"] compare:peanuts
options:NSCaseInsensitiveSearch range:range] == NSOrderedSame) {
src = [element getAttribute:@"SRC"];
}
}
image = [[NSImage alloc] initWithContentsOfURL:url];