tDiaryのdisp_referrerプラグインで、検索結果からのリンクの場合にキーワードを抽出する機能がある。URLの中にあるエンコードされた文字列を取り出すというものだが、次のようにURLがネストしている場合の指定が困難だった。

http://images.google.co.jp/imgres?imgurl=http://d.akinori.org/images/20041116_0.jpg&imgrefurl=http://d.akinori.org/%3Fdate%3D20041116&h=320&w=240&sz=27&hl=ja&start=79&um=1&tbnid=KRQt9Qd57q_uNM:&tbnh=118&tbnw=89&prev=/images%3Fq%3Dkinesis%26start%3D60%26ndsp%3D20%26svnum%3D10%26um%3D1%26hl%3Dja%26lr%3Dlang_ja%26c2coff%3D1%26safe%3Doff%26client%3Dfirefox%26rls%3Dorg.mozilla:ja:official%26sa%3DN

 そこで、できるようにハックしてみましたよ。"prev>q"で「prevの中のq」という指定になる。

Index: disp_referrer.rb
===================================================================
--- disp_referrer.rb	(revision 80)
+++ disp_referrer.rb	(working copy)
@@ -753,18 +753,17 @@
 			title = nil
 			keyword = nil
 			cached_url = nil
-			values = query ? DispRef2String::parse_query( query ) : nil
 			catch( :done ) do
-				setup['search_engines'][engine].each do |e|
-					if( e[0] =~ urlbase ) then
-						title = eval( e[1] )
+				setup['search_engines'][engine].each do |re_url, title, keys, cache|
+					if( re_url =~ urlbase ) then
+						title = eval( title )
 						throw :done if keyword
-						if e[2].empty? then
+						if keys.empty? then
 							keyword = setup['search.unknown_keyword']
 							throw :done
 						end
-						if String == e[2].class then
-							k, c = (query ? query : @url ).instance_eval( e[2] )
+						if String == keys.class then
+							k, c = (query ? query : @url ).instance_eval( keys )
 							if k then
 								keyword = k
 							else
@@ -773,15 +772,16 @@
 							cached_url = c ? c : nil
 							throw :done
 						else	# should be an Array usually
-							if not values then
-								keyword = setup['search.unknown_keyword']
-								throw :done
-							end
-							e[2].each do |k|
-								if( values[k] and not values[k][0].empty? ) then
-									unless( e[3] and e[3] =~ values[k][0] ) then
+							keys.each do |kpath|
+								value = nil
+								unless( kpath.split( '>' ).inject( query ) { |q, k|
+									value, = DispRef2String::parse_query( q.sub( /.*?\?/, '' ) )[k]
+									break nil if value.nil?
+									setup.to_native( DispRef2String::unescape( value ) )
+								}.nil? ) then
+									unless( cache and cache =~ value ) then
 										cached_url = nil
-										keyword = values[k][0]
+										keyword = value
 										throw :done
 									else
 										cached_url = $1
@@ -789,6 +789,10 @@
 										throw :done
 									end
 								end
+							end
+							if( keyword.nil? ) then
+								keyword = setup['search.unknown_keyword']
+								throw :done
 							end
 						end
 					end
Index: ja/disp_referrer.rb
===================================================================
--- ja/disp_referrer.rb	(revision 82)
+++ ja/disp_referrer.rb	(working copy)
@@ -445,7 +445,8 @@
 		[%r{\Ahttp://.*?\bgoogle\.([^/]+)/.*url}i, '".#{$1}のGoogleのURL検索?"', ['as_q', 'q'], DispReferrer2_Google_cache],
 		[%r{\Ahttp://.*?\bgoogle/search}i, '"たぶんGoogle検索"', ['as_q', 'q'], DispReferrer2_Google_cache],
 		[%r{\Ahttp://eval.google\.([^/]+)}i, '".#{$1}のGoogle Accounts"', [], nil],
-		[%r{\Ahttp://images\.google\.([^/]+)/(?:imgres|images)}i, '".#{$1}のGoogleイメージ検索"', ['q', 'imgurl'], DispReferrer2_Google_cache],
+		[%r{\Ahttp://images\.google\.([^/]+)/images}i, '".#{$1}のGoogleイメージ検索"', ['q'], DispReferrer2_Google_cache],
+		[%r{\Ahttp://images\.google\.([^/]+)/imgres}i, '".#{$1}のGoogleイメージ検索"', ['prev>q'], DispReferrer2_Google_cache],
 	],
 	'yahoo' => [
 		[%r{\Ahttp://[^/]+\.rd\.yahoo\.([^/]+)}i, '".#{$1}のYahooのリダイレクタ"', 'split(/\*/)[1]', nil],

 inject()のあたりがいまいちすっきりしないのは、デコード前の文字列を返す仕様になっているため。まあ、とりあえず動くからいいでしょう。

追記: querynilかもしれないので、以下の修正が必要です。

Index: disp_referrer.rb
===================================================================
--- disp_referrer.rb	(revision 86)
+++ disp_referrer.rb	(working copy)
@@ -774,7 +774,7 @@
 						else	# should be an Array usually
 							keys.each do |kpath|
 								value = nil
-								unless( kpath.split( '>' ).inject( query ) { |q, k|
+								unless( kpath.split( '>' ).inject( query ? query : @url ) { |q, k|
 									value, = DispRef2String::parse_query( q.sub( /.*?\?/, '' ) )[k]
 									break nil if value.nil?
 									setup.to_native( DispRef2String::unescape( value ) )


Categories : Tech