BookShelfver='$Id: bookshelf.rb,v 1.8 2005/05/07 09:08:48 waka Exp waka $'.split(" ")[2]
=begin
nDiary プラグイン
機能:
ブクログ(http://booklog.jp/)風本棚プラグイン。
amazon_shop で紹介した商品を本棚に陳列し、表示する。
制限:
・amazon_shop.rb 使用していないと意味なし
・yaml 形式のキャッシュファイルのみ対応
使用方法:
HTML ファイルの本棚を表示したい場所に
と書くだけです。
なお以下のオプションが指定できます。(指定しな場合はデフォルト値が使われます)
option:
direction=h or v h: 横に並べる デフォルト値
v: 縦に積む
rank=d or r d: 掲載日付順に並べる デフォルト値
r: ランダムに並べる
skipnoimg=n or y n: 画像のない商品も並べる デフォルト値
y: 画像のない商品は並べない
example: 縦に積み、ランダムに並べる、画像のない商品は並べない
カスタマイズ方法:
ndiary.conf で以下の設定が可能(設定しなくても動作します)。
# 本棚プラグイン(bookshelf.rb)用
BOOKSHELF_WIDTH = "640" # 本棚幅(デフォルト:320)
BOOKSHELF_RANK = "2" # 1:掲載日付順(デフォルト) / 2:ランダム
BOOKSHELF_POPUP_DELAY = "0.1" # マウスオーバーしてから画像をポップアップさせるまでの時間(秒)
BOOKSHELF_SKIP_NO_IMG = true # true:画像があるものだけ表示 / false:画像がなくても表示(デフォルト)
BOOKSHELF_BACK_IMG = "./img/shelf.png" # 本棚の画像へのパス(デフォルト:なし)
また、以下の amazon_shop.rb 用の設定も一部有効になります。
BOOKSTORE_AMAZON_ID
NO_IMAGE_FILE
※画像ポップアップに使用される JavaScript や画像を表示する HTML 部分は
ブクログで使用されているものを参考にして、nDiary 用に改変しました。
Special Thanx
mas さん: 縦積みパッチ
http://home3.highway.ne.jp/mas/diary/200410b.html#d13_t1
しのさん: 日付順並び不具合修正および上記パッチあてなど
http://www.pat.hi-ho.ne.jp/tatsumi-da/200501.html#14_t1
=end
def plug(opt)
require 'yaml'
require 'date'
javaScriptD = @diary.outputDirectory
amazonShopCacheD= @diary.logDirectory + 'amazon_shop'
amazonID = ""
noImg = ""
shelfHeightMode = false
shelfRank = 1 # 1:掲載日付順 / 2:ランダム
shelfWidth = 320
shelfPopupDelay = 0.1
shelfBackImg = ""
shelfSkipNoImg = false # true:画像があるものだけ表示 / false:画像がなくても表示
shelfPopupTextDecorate = "border-style:none none solid solid;border-color: #0af;font-color:navy; background:#fff;"
unless @diary.config['BOOKSTORE_AMAZON_ID'].to_s.empty? then
amazonID = @diary.config['BOOKSTORE_AMAZON_ID'].to_s
end
unless @diary.config['NO_IMAGE_FILE'].to_s.empty? then
noImg = @diary.config['NO_IMAGE_FILE'].to_s.gsub(/.*src="(.+?)".*/,"\\1")
end
unless @diary.config['BOOKSHELF_HEIGHT_MODE'].to_s.empty? then
shelfHeightMode = @diary.config['BOOKSHELF_HEIGHT_MODE']
end
unless @diary.config['BOOKSHELF_RANK'].to_s.empty? then
shelfRank = @diary.config['BOOKSHELF_RANK'].to_i
end
unless @diary.config['BOOKSHELF_WIDTH'].to_s.empty? then
shelfWidth = @diary.config['BOOKSHELF_WIDTH'].to_i
end
unless @diary.config['BOOKSHELF_POPUP_DELAY'].to_s.empty? then
shelfPopupDelay = @diary.config['BOOKSHELF_POPUP_DELAY'].to_f
end
unless @diary.config['BOOKSHELF_SKIP_NO_IMG'].to_s.empty? then
shelfSkipNoImg = @diary.config['BOOKSHELF_SKIP_NO_IMG']
end
unless @diary.config['BOOKSHELF_BACK_IMG'].to_s.empty? then
shelfBackImg = @diary.config['BOOKSHELF_BACK_IMG'].to_s
end
case opt['direction']
when /v(ertical)?/i
shelfHeightMode = true
when /h(orizontal)?/i
shelfHeightMode = false
end
case opt['rank']
when /r(andom)?/i
shelfRank = 2
when /d(ate)?/i
shelfRank = 1
end
case opt['skipnoimg']
when /y(es)?/i
shelfSkipNoImg = true
when /n(o)?/i
shelfRank = no
end
bookWidth = 7
displayNum = (shelfWidth / bookWidth).to_i
imgTotalWidth = displayNum * bookWidth
def randAry(n, m)
s = []
((n-m)...n).each do |j|
t = rand(j+2)
s.concat s.include?(t) ? [j+1] : [t]
end
return s
end
cacheList = Array.new
imgMaxHeight = -1
asinList = Array.new
cntDf = 0
case shelfRank
when 1
nowY, nowM = Time.now.strftime("%Y/%m").split("/")
targetFiles = Array.new
(nowY.to_i-2..nowY.to_i).to_a.reverse.each{|year|
Dir::find(File.join(@logDirectory,year)){|file|
if /^\d{8}\.diary$/i =~ File.basename(file) then
targetFiles << file
end
}
}
targetFiles.sort.reverse.each{|file|
File.open(file).read.each{|df|
asinCode = ""
if /[\((][@@](CD|DVD|PS|PS2|GC|XBOX|GBA|ASIN|ISBN)[::](.+?)(\/.+?)?[\))]/mi =~ df then
key = $1
asinCode = $2
end
unless asinCode.to_s.empty? then
begin
next if /(template)|(list)|(simple)|(tmpl_oneline.*)/ =~ asinCode
if FileTest.exist?(File.join(amazonShopCacheD, asinCode)) then
cache = File.open(File.join(amazonShopCacheD, asinCode),mode="r")
else
next
end
begin
str = YAML::load(cache)
rescue
next
end
rescue
if $DEBUG then
$stderr.puts $!
$stderr.puts File.join(amazonShopCacheD, file)
end
next
end
ddate = str["日記記載日"]
asin = str["ASIN"]
title = str["商品タイトル"].to_s.gsub(/^.+?>(.+?)<.+?$/,"\\1")
author = str["出演者/著者"].to_s.gsub(/<.+?>/,"")
artist = str["メーカー"].to_s.gsub(/<.+?>/,"")
imgUrl = str["画像URL"]
imgWidth = str["画像幅"].to_i
imgHeight = str["画像高さ"].to_i
media = str["メディア"]
if shelfSkipNoImg then
next if imgUrl.to_s.empty?
end
unless asinList.include?(asin) then
asinList << asin
cacheList << sprintf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",ddate,asin ,imgUrl,imgWidth,imgHeight,title,author,artist ,media)
cntDf += 1
imgMaxHeight = imgHeight if imgHeight > imgMaxHeight
end
break if cntDf > displayNum
end
}
}
when 2
asinList = Array.new
Dir.entries(amazonShopCacheD).each{|file|
next if FileTest.directory?(file)
begin
next if /(template)|(list)|(simple)|(tmpl_oneline.+)/ =~ file
if FileTest.exist?(File.join(amazonShopCacheD, file)) then
cache = File.open(File.join(amazonShopCacheD, file),mode="r")
else
next
end
begin
str = YAML::load(cache)
title = str["商品タイトル"].to_s.gsub(/^.+?>(.+?)<.+?$/,"\\1")
imgUrl = str["画像URL"]
imgWidth = str["画像幅"].to_i
cache.close
next if title.to_s.empty?
if shelfSkipNoImg then
next if imgUrl.to_s.empty?
next if imgWidth < 10
end
rescue
if $DEBUG then
$stderr.puts $!
$stderr.puts File.join(amazonShopCacheD, file)
end
next
end
rescue
next
end
asinList << file
}
asinRand = Array.new
#randNum = displayNum * 2
#randNum = asinList.size if asinList.size >= randNum
randNum = displayNum
randAry(asinList.size, randNum).each{|i|
asinRand << asinList[i - 1]
}
asinRand.each{|asinCode|
cache = File.open(File.join(amazonShopCacheD, asinCode),mode="r")
str = YAML::load(cache)
ddate = str["日記記載日"]
asin = str["ASIN"]
title = str["商品タイトル"].to_s.gsub(/^.+?>(.+?)<.+?$/,"\\1")
author = str["出演者/著者"].to_s.gsub(/<.+?>/,"")
artist = str["メーカー"].to_s.gsub(/<.+?>/,"")
imgUrl = str["画像URL"]
imgWidth = str["画像幅"].to_i
imgHeight = str["画像高さ"].to_i
media = str["メディア"]
#if shelfSkipNoImg then
#next if imgUrl.to_s.empty?
#end
cacheList << sprintf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",ddate,asin ,imgUrl,imgWidth,imgHeight,title,author,artist ,media)
if shelfHeightMode then
imgMaxHeight = imgWidth if imgWidth > imgMaxHeight
else
imgMaxHeight = imgHeight if imgHeight > imgMaxHeight
end
cntDf += 1
break if cntDf > displayNum
}
end
body = Array.new
num = 1
xShift = 10
cacheList.each{|i|
next if i.nil?
ddate, asin, imgUrl, imgWidth, imgHeight, title, author,artist, media = i.split("\t")
xShiftsize = bookWidth
if imgUrl.to_s.empty? then
imgUrl = noImg
imgWidth = 100
imgHeight = 140
end
author = artist if author.to_s.empty?
if shelfHeightMode then
imgHeightSmall = imgWidth.to_i * 2 / 3
else
imgHeightSmall = imgHeight.to_i * 2 / 3
end
unless amazonID.to_s.empty?
amazonProductUrl = "http://www.amazon.co.jp/exec/obidos/ASIN/#{asin}/#{amazonID}/ref=nosim"
else
amazonProductUrl = "http://www.amazon.co.jp/exec/obidos/ASIN/#{asin}/"
end
if num > 1
xShift = xShiftsize + xShift
else
xShift = 0
end
topPos = imgMaxHeight - imgHeightSmall - 40
body << %Q||
body << %Q!!
if shelfHeightMode then
topPos = ( imgMaxHeight - ( imgHeightSmall / 2 ) ) - 60
body << %Q!' : '>')
body << %Q!!
body << %Q!
' : '>')
body << %Q!【#{media.chop}】#{title}/#{author}[紹介した日:#{ddate.scan(/(\d\d\d\d)(\d\d)(\d\d)/).flatten.join("/")}]!
else
body << %Q!
' : '>')
body << %Q!!
body << %Q!
' : '>')
body << %Q!【#{media.chop}】#{title}/#{author}[紹介した日:#{ddate.scan(/(\d\d\d\d)(\d\d)(\d\d)/).flatten.join("/")}]!
end
num += 1
break if num > displayNum
}
shelfImg = ""
unless shelfBackImg.empty? then
shelfImg = %Q!
' : '>')
end
bookShelfLoadJS = open(File.join(javaScriptD,"bookshelf.js"),"w")
bookShelfLoadJS.puts bookshelfjs(shelfPopupDelay)
bookShelfLoadJS.close
bookShelfListJS = open(File.join(javaScriptD,"bookshelfimages.js"),"w")
bookShelfListJS.puts %Q!document.write('#{shelfImg}#{body.to_s.kconv(@diary.outputKcode)}');!
bookShelfListJS.close
# 横置き時の高さを調整(画像最大高さ * 2/3 + 10 px)
if ! shelfHeightMode then
shelfWidth = imgMaxHeight * 2 / 3 + 10
end
str = %Q!\n