Abcver='$Id: abc.rb,v 1.10 2005/09/22 17:55:36 waka Exp waka $'.split(" ")[2] # http://www.double-red.net/ =begin nDiary filter abc.rb(Amazon Bk1 Collaboration) bk1(http://www.bk1.co.jp) から書誌情報と書影を取得(ファイルダウンロード)、 amazon_shop フィルタ取得情報で書影がない時に書影を補完、表示する。 具体的な動作 (1)amazon_shop キーの (@ISBN:isbn) に反応。 (2)amazon_shop フィルタ動作前に bk1 から簡単な書誌情報と画像を(存在していれば)ダウンロードする。 (3)amazon_shop フィルタ動作後、amazon からの取得情報内に書影がない場合(2)の書影で補完、表示。 なお、一歩さん(http://ippo.s5.xrea.com/ndiary/)謹製の bookstore_x (http://ippo.s5.xrea.com/ndiary/inlink.html) を常用していて、 bk1 ダウンロード書影ファイルすでに存在している場合、新規取得せずにそっちを使用します(たぶん)。 設定方法(bookstore_x 常用している方は(2)以外特に設定しなくていいはず) ※必ず FILTER = 'abc' は FILTER = 'amazon_shop' の前に記述する事!!!! (1)ndiary.conf の設定 # bookstore_x と共有できる設定 CACHE_DIRECTORY = '/hoge/foo/ndiary/log/bookcache/' #キャッシュファイル格納場所 PROXY = 'proxy.hoge.com:8080' # プロキシ(使用していない場合は記述しない) # bk1の画像利用(ダウンロード)指定(画像格納フォルダ) BOOKSTORE_BK1_IMAGE = '/hoge/foo/bar/img/bk1img/' # ダウンロード位置(必須) BOOKSTORE_BK1_IMAGEURL = './' # リンク位置(htmlにはこちらが記述される)(必須) BOOKSTORE_BK1_ID = 'p-waka54821' # bk1 ブリーダー ID(適宜) # abc 独自設定(適宜) # amazon / bk1 への商品直接リンクテンプレート。記述なければデフォルト表示。 #ABC_LINK_DECORATE = '["[bk1,amz]","a タグの要素","a タグ内 title 属性の値"]' # 例 ABC_LINK_DECORATE = '<-isbn>: 【["bk1","bk1 へのリンク","<-title>(bk1)"]】【["amz","amazon へのリンク","<-title>(amazon)"]】' # ["A,"B","C"] A: bk1 or amz # B,C: B # B,C: では以下のキーワードも定義可能。 # <-isbn>: 商品の ISBN # <-isbn_nodash>: 商品の '-' なし ISBN(4-123-45678-9 = > 4123456789) # <-title>: 商品の(bk1 における)タイトル # <-bk1id>: bk1 ブリーダー ID # <-amzid>: amazon アソシエイト ID (2)キャッシュディレクトリ(bk1_light)作成(必須) (1)で設定した CACHE_DIRECTORY を作成、 さらにその下に 'bk1_light' というディレクトリを作成する。 (例) CACHE_DIRECTORY = '/hoge/foo/ndiary/log/bookcache/' の場合、 /hoge/foo/ndiary/log/bookcache/bk1_light を作成する。 (3))ruby ライブラリを準備する(必須) webagent (一歩さんところから取得下さい) http://ippo.s5.xrea.com/ndiary/user/lib/webagent.rb cookie (一歩さんのところから取得下さい) http://ippo.s5.xrea.com/ndiary/user/lib/cookie.rb image_size => 必須ではなくなりました(ver 1.9から) http://raa.ruby-lang.org/list.rhtml?name=image_size yaml (ruby 1.8.x では標準) =end class Module def attr_my_accessorbk1(name) module_eval %{ def #{name.id2name}() get_bk1data @#{name.id2name} end } end end class Bk1Light attr_accessor :urlSite, :searchUrl attr_accessor :isbn attr_accessor :expire attr_accessor :diary_day attr_accessor :cached_day, :cache_dir, :cache_file attr_accessor :image_dir, :image_download attr_accessor :image_width, :image_height attr_my_accessorbk1 :image_url attr_my_accessorbk1 :bibid attr_my_accessorbk1 :product_url attr_my_accessorbk1 :local_img attr_my_accessorbk1 :title def initialize @expire = 0 # 0だと存在するキャッシュを必ず使用 @image_download = false @urlSite = 'http://www.bk1.co.jp/' @diary_day = Time.now @cached_day = Time.now @flag = false @title = nil @local_img = nil @image_url = nil @image_width = nil @image_height = nil @media = nil @product_url = nil @cache_dir = "" @cache_file = "" end def load_cache begin if @flag or (File::directory?(@cache_dir.to_s) and File::readable?(@cache_dir + @cache_file) and File::mtime(@cache_dir + @cache_file).to_i < Time::now.to_i - 3600 * 24 * @expire and @expire != 0) then return end rescue puts "cache_file= " + @cache_file.to_s puts $! end @flag = true read_cache end def read_cache cache_file = File.join(@cache_dir, @cache_file) if /\.txt/i =~ @cache_file then return unless FileTest.exist?(cache_file) cache = File.open(cache_file,mode="r") cache.read.to_a.each{|line| @title = $1.tosjis if /^title\t(.+?)$/ =~ line @bibid = $1 if /^id\t(.+?)$/ =~ line @isbn = $1 if /^isbn\t(.+?)$/ =~ line } cache.close else unless FileTest.exist?(cache_file) then @flag = nil return end cache = File.open(cache_file,mode="r") str = YAML::load(cache) @title = str["商品タイトル"] @product_url = str["商品URL"] @image_url = str["画像URL"] @image_width = str["画像幅"] @image_height = str["画像高さ"] @media = str["メディア"] @diary_day = str["日記記載日"] @cached_day = str["キャッシュした時間"] @isbn = str["ISBN"] @bibid = str["BIBID"] @local_img = str["ローカル画像"] # 2005/4/10 bk1 リニューアル @product_url = @product_url.to_s.gsub(/cgi-bin.+?$/,"product/#{@bibid}") cache.close end end def save_cache return unless File::directory?(@cache_dir.to_s) cache_file = File.join(@cache_dir, @cache_file) str = Hash[\ "商品タイトル",@title,\ "商品URL",@product_url,\ "画像URL",@image_url,\ "画像幅",@image_width,\ "画像高さ",@image_height,\ "メディア",@media,\ "日記記載日",@diary_day,\ "キャッシュした時間",@cached_day,\ "ISBN",@isbn,\ "BIBID",@bibid,\ "ローカル画像",@local_img,\ "FilterVersion",Abcver\ ] cache = File.open(cache_file,mode="w") cache.write(str.to_yaml) cache.close end def get_bk1data load_cache return if @flag @searchUrl = @urlSite + "search/search.asp?" @searchUrl << "kywd=#{@isbn}" puts "CHK; get #{@searchUrl}" agent = WebAgent.new() agent.uri = @searchUrl getstart = Time.now begin agent.get() puts " Time: #{Time.now - getstart}(sec)" rescue puts " Time Out: #{Time.now - getstart}(sec)" return false end body = agent.body.gsub!(/[\r\n]/,"") bibid = Array.new body.scan(//){ bibid << $1 unless $1.nil? } @bibid = bibid.first if @bibid.to_s.empty? save_cache return end body.scan(/src="\/(bookimages\/.+?#{@bibid}.+?_s.jpg)"/){ @image_url = $1.gsub(/_s/,"") unless $1.nil? @image_url = File.join(@urlSite,@image_url) } body.scan(/#{@bibid}">(.+?)<\/font>/mi){ @title = $1.to_s } @product_url = @urlSite + "product/#{@bibid}" if @local_img.to_s.empty? then if @image_download do_image_download end end @title = @title.tosjis # if @bibid.to_s.empty? then if @title.to_s.empty? then read_cache else save_cache @flag = true end end def do_image_download if @image_url.nil? @local_img = "" return end image_file_name = File.join(@image_dir, "isbn#{@isbn.to_s.delete('-').downcase}.jpg") unless FileTest.exist?(image_file_name) then begin agent = WebAgent.new() puts "CHK; get #{@image_url}" agent.uri = @image_url agent.get() fp = open(image_file_name, 'wb') fp.puts agent.body fp.close rescue # timeout: no image end end if FileTest.exist?(image_file_name) then if FileTest.size(image_file_name) < 1000 then # ファイルサイズが 1000 byte 以下はファイル無し get_image_size @local_img = "" else @local_img = "isbn#{@isbn.to_s.delete('-').downcase}.jpg" end end end def get_image_size image_file_name = File.join(@image_dir, "isbn#{@isbn.to_s.delete('-').downcase}.jpg") if FileTest.exist?(image_file_name) then # image = ImageSize.new(open(image_file_name,"r").read) # @image_width, @image_height = image.get_width.to_i, image.get_height.to_i @image_width, @image_height = ImageSize::size(image_file_name) end end end class Filter def abc(str, type) $:<< @diary.config['USER_LIB_DIRECTORY'] begin require 'cookie' require 'webagent' #require 'image_size' require 'lib/imagesize' require 'yaml' rescue LoadError puts $! end tagend = @diary.isXHTML ? ' />' : '>' bk1id, amzid = '', '' unless @diary.config['BOOKSTORE_BK1_ID'].to_s.empty? bk1id = @diary.config['BOOKSTORE_BK1_ID'] end unless @diary.config['BOOKSTORE_AMAZON_ID'].to_s.empty? amzid = @diary.config['BOOKSTORE_AMAZON_ID'] amzid = amzid end startFlagStr = "bk1_lightFlagStart" endFlagStr = "bk1_lightFlagEnd" case type when :P, :UL, :DL str.gsub!(/\(@ISBN:(.+?)(\/.+?)?\)/){ isbn = $1.to_s tmptemplate = $2.to_s bk1Light = Bk1Light.new bk1Light.isbn = isbn title = "" product_url = "" # bookstore_x のキャッシュをロードする bk1Light.cache_dir = File.join(@diary.config['CACHE_DIRECTORY'],'bk1') bk1Light.cache_file = "isbn#{isbn.delete('-').downcase}.txt" unless @diary.config['BOOKSTORE_BK1_IMAGE'].to_s.empty? then bk1Light.image_download = true bk1Light.image_dir = @diary.config['BOOKSTORE_BK1_IMAGE'] end title = bk1Light.title.to_s product_url = bk1Light.urlSite + "search/search.asp?kywd=#{bk1Light.isbn}" if title.to_s.empty? then bk1Light = Bk1Light.new bk1Light.isbn = isbn bk1Light.cache_dir = File.join(@diary.config['CACHE_DIRECTORY'],'bk1_light') bk1Light.cache_file = isbn unless @diary.config['BOOKSTORE_BK1_IMAGE'].to_s.empty? then bk1Light.image_download = true bk1Light.image_dir = @diary.config['BOOKSTORE_BK1_IMAGE'] end title = bk1Light.title.to_s product_url = bk1Light.product_url.to_s end retstr = "" unless title.to_s.empty? then bk1link = product_url.gsub(/\.$/,"") + "/?partnerid=" + bk1id + "/" amzlink = %Q'http://www.amazon.co.jp/exec/obidos/ASIN/#{isbn.delete("-")}/#{amzid}/ref=nosim' # abc リンクテンプレート使用 if @diary.config['ABC_LINK_DECORATE'].to_s.empty? then amzbk1link= %Q'ISBN: #{bk1Light.isbn}【bk1】【amazon】' else abcdecorate = @diary.config['ABC_LINK_DECORATE'].to_s.gsub(/<-isbn>/,"#{bk1Light.isbn}").gsub(/<-title>/,"#{bk1Light.title}").gsub(/<-isbn_nodash>/,"#{bk1Light.isbn.delete("-")}").gsub(/<-bk1id>/,bk1id).gsub(/<-amzid>/,amzid) # [bk1,amz]decorate = ["[bk1,amz]","a タグの要素","a タグ内 title 属性の値"] bk1decorate = abcdecorate.scan(/\["(bk1)","(.+?)","(.+?)"\]/).flatten amzdecorate = abcdecorate.scan(/\["(amz)","(.+?)","(.+?)"\]/).flatten amzbk1link = abcdecorate.to_s.gsub(/\["bk1.+?"\]/,%Q'#{bk1decorate[1]}').gsub(/\["amz.+?"\]/,%Q'#{amzdecorate[1]}') end # amazon_shop マイナー機能の一時的テンプレートロード時はスキップ unless tmptemplate.to_s.empty? then retstr = %Q'(@ISBN:#{isbn}#{tmptemplate})#{amzbk1link}' else retstr = %Q|(@ISBN:#{bk1Light.isbn})#{amzbk1link}| end else amzlink = %Q'http://www.amazon.co.jp/exec/obidos/ASIN/#{isbn.delete("-")}/#{amzid}/ref=nosim' # abc リンクテンプレート使用 if @diary.config['ABC_LINK_DECORATE'].to_s.empty? then amzbk1link= %Q'ISBN: #{bk1Light.isbn}【bk1】【amazon】' else abcdecorate = @diary.config['ABC_LINK_DECORATE'].to_s.gsub(/<-isbn>/,"#{bk1Light.isbn}").gsub(/<-title>/,"#{bk1Light.title}").gsub(/<-isbn_nodash>/,"#{bk1Light.isbn.delete("-")}").gsub(/<-bk1id>/,bk1id).gsub(/<-amzid>/,amzid) # [bk1,amz]decorate = ["[bk1,amz]","a タグの要素","a タグ内 title 属性の値"] bk1decorate = abcdecorate.scan(/\["(bk1)","(.+?)","(.+?)"\]/).flatten amzdecorate = abcdecorate.scan(/\["(amz)","(.+?)","(.+?)"\]/).flatten amzbk1link = abcdecorate.to_s.gsub(/\["bk1.+?"\]/,%Q'#{bk1decorate[1]}').gsub(/\["amz.+?"\]/,%Q'#{amzdecorate[1]}') end retstr = %Q|(@ISBN:#{isbn})#{amzbk1link}| end retstr + "" } when :AFTER_ONEDAY unless @diary.config['BOOKSTORE_BK1_IMAGE'].to_s.empty? image_dir = @diary.config['BOOKSTORE_BK1_IMAGE'] image_url = @diary.config['BOOKSTORE_BK1_IMAGEURL'] w,h = nil, nil str.gsub!(/(.+?)/mi){ isbn = $1.to_s body = $2.to_s bk1Light = Bk1Light.new bk1Light.isbn = isbn title = "" product_url = "" # bookstore_x のキャッシュをロードする bk1Light.cache_dir = File.join(@diary.config['CACHE_DIRECTORY'],'bk1') bk1Light.cache_file = "isbn#{isbn.delete('-').downcase}.txt" title = bk1Light.title.to_s product_url = bk1Light.urlSite + "search/search.asp?kywd=#{bk1Light.isbn}" if title.to_s.empty? then bk1Light = Bk1Light.new bk1Light.isbn = isbn bk1Light.cache_dir = File.join(@diary.config['CACHE_DIRECTORY'],'bk1_light') bk1Light.cache_file = isbn title = bk1Light.title.to_s product_url = bk1Light.product_url.to_s end bk1link = product_url.gsub(/\.$/,"") + "/?partnerid=" + bk1id + "/" image_file = bk1Light.local_img if bk1Light.image_width.to_s.empty? || bk1Light.image_height.to_s.empty? then bk1Light.image_dir = image_dir bk1Light.get_image_size bk1Light.save_cache end if bk1Light.image_width.to_i > 0 then image_width = " width=#{bk1Light.image_width}" end if bk1Light.image_height.to_i > 0 then image_height = " height=#{bk1Light.image_height}" end if FileTest.exist?(File.join(image_dir,image_file)) and FileTest.file?(File.join(image_dir,image_file)) # ↓ファイルサイズが 1000 byte 以下はファイル取得失敗している(= 画像無し)とみなす unless FileTest.size(File.join(image_dir,image_file)) < 1000 then linkstr = %Q!! unless @diary.config['NO_IMAGE_FILE'].to_s.empty? no_image_file = @diary.config['NO_IMAGE_FILE'].to_s body.gsub!(/#{no_image_file}/,linkstr) else body.gsub!(/No Image<\/div>/mi,linkstr) end end end body } end end end end