ブクログにあるかをアマゾンに表示するグリースモンキー

二泊三日で開発合宿ちっくなものに行ってきた。
金曜夜に会社から直行というのは、なかなか良い感じ。
つくったというか、既存のものをちょっと書き換えただけだが、
ブクログ(http://booklog.jp/)とアマゾンをちょっとつないでみた。
合宿成果第一弾。

参考書

しつこいかもしれないが、自分はプログラマーでもSEでもない。
エンジニアといってもクリーンルームにいるエンジニアだった。
greasemonkeyが楽しそうだったんで、Hello Worldみたいな
基礎的なところからのスタートである。参考書はこれ。

Greasemonkeyスクリプティング TIPS&SAMPLES
Greasemonkeyスクリプティング TIPS&SAMPLES高山 恭介

おすすめ平均
stars開発者向けならばもう一歩踏み込んでも

Amazonで詳しく見る
by G-Tools

Javascriptのリファレンスを持ってきてくれてる人がいたんで、それも使った。
,と.を一カ所間違って動かないよーというレベルということを断っておく。

動機

蔵書流動化をいろいろと考えていた。友達と本をシェアすると
面白いし経済的じゃないかということである。
そのためには友達がどんな本を持っているか知らないと
いけないわけで、ブクログに登録しとこうよってことだけど
ブクログにいちいち見に行くのが面倒だなと感じる。
その人が持っているものがアマゾンでわかるとよくね?
という思ったので、それをつくってみた。
jtpaグループ - phoの日記 - 蔵書流動化計画
http://jtpa.g.hatena.ne.jp/pho/20061210/p1
12月に自分で考えたのがそのまま形になった感じ。

作り方

イメージはあるんだけど、作り方が全然わかんないので
てってーてきにパクる(TTP)。権利関係よくわかんないけど。
図書館にリンクを貼るスクリプトもあったんだけど、
紀伊国屋の在庫をアマゾンで見るスクリプトが素晴らしく
シンプルだったので、これをちょこちょこ書き換えてみた。
worris' works - Greasemonkey - Amazon Kinokuniya Linky
http://worris.sakura.ne.jp/greasemonkey.html
個人的にかなり感動したのはこの部分。

document.body.parentNode.innerHTML.match(/ASIN:[^4]*(4(\d{8}|-[\d-]{9}-)[\dX])/);

たった一行でアマゾンからasinを取得しているのがすごい。
アマゾンのURLってけっこう冗長性があるというか
いろんなのからアクセスできるのに、たった一行で
カバーしている。正規表現って強力だと感じた。
asin取得すれば、ブクログの該当URLはすぐわかる。

var url="http://booklog.jp/asin/"+asin;

後ろにasinをつければ終了。
そこからGETでページを取得して、ページ内検索。

var m1=response.responseText.match("lazysuits")

ここにブクログのユーザidを入れている。
ブクログのページのソースを見ればわかると思うけど
○○さんの本棚というリンクが並んでるので
ページ内にその人のユーザidがあれば、その人が
その本を持っているということがわかる。
ここでは4人登録している。書き方がアホっぽいな。
配列を使えばいいと後で気づいたが、面倒なのでやめた。
もっとアホっぽい箇所がある。

if(m1==null)m1=' ';

見つからなかったときの返り値がnullで、そのままnullと
表示されたんで、スペースにしとこうかなという感じ。
4つも並んでると頭悪すぎ。配列でいいって思ったけど
あんまよく覚えてないし、そもそもnullって返り値自体を
なんか別の方法で変えられるような気がした。
そういえば最後もひどいな。
4人くらい表示するときいちいち改行したら場所を
取りすぎるんじゃないかと思って、カンマで区切るのも
なんかいまいちだったんで背景色を変えてみた。
どうせ繰り返しなんだからもっときれいに書けるはず。

ソース

// ==UserScript==
// @name          Amazon BookLog Linky
// @namespace     http://booklog.jp/
// @description	  Booklog Lookup from Amazon book listings.
// @include       http://*.amazon.*
// ==/UserScript==

libsearch();

function libsearch() {
	// mainmatch = window._content.location.href.match(/\/(\d{9}[\d|X])\//);
	// var href = document.location.href;
	// var index = href.indexOf('ASIN');
	// var asin = href.substring(index+5,index+15);
	document.body.parentNode.innerHTML.match(/ASIN:[^4]*(4(\d{8}|-[\d-]{9}-)[\dX])/);
	// if (asin.match(/(4\d{8}[\d|X])/)){
	if (RegExp.$1!=''){
		// var isbn = mainmatch[1];
		var asin = RegExp.$1
		//var url="http://worris.sakura.ne.jp/kinokuniya.cgi?W-ISBN="+asin;
		var url="http://booklog.jp/asin/"+asin;
		GM_xmlhttpRequest({
			method:"GET",
			url: url,
			onload:function(response) {
				//var m=response.responseText.match(/<zaiko>.*<\/zaiko>/i)
				var m1=response.responseText.match("lazysuits")
				var m2=response.responseText.match("kany1120")
				var m3=response.responseText.match("marqs")
				var m4=response.responseText.match("futa")
				var header = document.evaluate("//b[@class='sans']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
				if (header) {
					var spl_link = document.createElement('a');
					//spl_link.setAttribute('href', 'http://bookweb.kinokuniya.co.jp/guest/cgi-bin/wshosea.cgi?W-ISBN='+ asin);
					if(m1==null)m1=' ';
					if(m2==null)m2=' ';
					if(m3==null)m3=' ';
					if(m4==null)m4=' ';
					spl_link.setAttribute('href', 'http://booklog.jp/asin/'+ asin);
					//spl_link.setAttribute('title', 'To Kinokuniya');
					spl_link.setAttribute('title', 'To BookLog');
					spl_link.innerHTML = '</br><span style=\"font-size:100%; background-color:#ffffcc;\">'+m1+'</span><span style=\"font-size:100%; background-color:#ffff00;\">'+m2+'</span><span style=\"font-size:100%; background-color:#ff00cc;\">'+m3+'</span><span style=\"font-size:100%; background-color:#ccff00;\">'+m4+'</span>';
					header.parentNode.insertBefore(spl_link, header.nextSibling);
				}
			}
		});
	}
}

感想

先人の知恵を使わせてもらうと意外とあっさりできた。
これを使ってもいいけど、もっと見やすいインターフェイスとか
もっと合理的なやつを書いてくれると非常にありがたい。
ブクログに本を大量に登録してる友達なんていないのが普通かな。
個人的にはこれで便利になったからどうでもいいや。
読みたい本があればブクマコミュニケーションすればいいし。