# $Id: bookstore.rb,v 1.12 2003/08/21 12:38:37 not Exp $
# filter/bookstore_x.rb 2004/01/08-2004/03/18 新キャッシュ用
=begin
usage:
文中の(ISBN4-04-873259-5)ないし(ISBN:4-04-873259-5)を
各オンライン書店へのリンクに変換
書店名・書影の有無・出荷状況・書評数等を書店毎に表示
書誌情報を表示
それらの情報をキャッシュに・から読書
(keyword:キーワード)で各書店のキーワード検索に変換(試装中)
(bibid:...)bk1
(注:キャッシュ用フォルダ(各書店毎)の作成必要
-> log/bookcache/amz/ 等)
(注:キャッシュ用・各書店情報解析用ライブラリ必要
-> user/lib/cookie.rb, webagent.rb, cache.rb, cachebib.rb, #多分必須
cachebib_simple.rb, cache_ippo.rb, #以下は状況に応じて
amazon.rb, bk1.rb, 等)
「ruby diary -nonet」というオプションで実行するとネット接続をせずに
キャッシュから生成
ndiary.conf に以下のような行を追加すると表示するオンライン書店と
その順番を指定
BOOKSTORE_SHOP_LIST = 'amazon bk1 yahoo asahiya jbook kinokuniya rakuten skysoft'
洋書の場合の指定
# ISBN0-xxx
BOOKSTORE_SHOP_LIST_0 = 'amazon amazon.com skysoft a1books powells kinokuniya maruzen'
# ISBN1-xxx
BOOKSTORE_SHOP_LIST_1 = 'amazon_uk bookshop'
指定できるオンライン書店(ほとんどが未だ完全実装せずですが)
amazon amazon.co.jp \s*
'
書評リンク(review-link)との連動では ndiary.conf に以下の行を追加
REVIEWER_CODE = '一歩' #自分のIDで
REVIEWLINK_URL = 'http://ippo.s5.xrea.com/diary/' #fileの存在URL,未対応
REVIEWLINK_LINK = true #書店リンクのうちに書評リンクも含める
BOOKSTORE_IMAGE = true #書影リスト(画像リスト)の別生成
reference:
松下さん(http://homepage3.nifty.com/akima/)
(http://www.alles.or.jp/~akihisa/)のオンライン書店へのリンク
細井さん(http://www.fan.gr.jp/~hosoi/diary/diary.html)による洋書リンク
(注:現在洋書書店の解析エンジンはできてません)
(注:cach_bib_tmp.rbによる無解析エンジンのみ)
他・amazon.rb, amazondvd.rb, webagent.rb等
customize: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ソース140行目あたりの
require の指定ファイルとキャッシュフォルダは各位で適時改変
アフィリエイトは直接ソースの100行目あたりを修正しても設定可能
(無指定だと一歩のアフィリエイトになる場合があります)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ToDo:
cacheに関係しない各書店のurlやkeyword部分は継承classでなくmodule化か?
note:
キャッシュ用フォルダは(各書店分も含め)あらかじめ作成してください
バグ)reviewlinkのcodeが日本語だと化ける場合があります
=end
class Filter
BOOKSTOREX = Regexp::compile(/[\((]ISBN[:|:]?\s?(\d-[\d-]{9}[-]?[\w]?)[\))]/) unless defined?(BOOKSTOREX)
BOOKSTORE_KEYWORD_SEARCH = Regexp::compile(/[\((]keyword[:|:]?\s?(.+?)[\))]/) unless defined?(BOOKSTORE_KEYWORD_SEARCH)
BK1_ID = Regexp::compile(/[\((]bibid[:|:]?\s?(.+?)[\))]/) unless defined?(BK1_ID)
STORE = Regexp::compile(/[\((]SHOP[:|:]?\s?(.+?),\s?(.+?)[\))]/) unless defined?(STORE)
def cachebibs_make ( bookstore_list = [] )
unless @flag_cachebibs_make #-----initialize-----
@flag_cachebibs_make = true
if @diary.respond_to?('config') then
@bk1_id = @diary.config['BOOKSTORE_BK1_ID'].to_s #'p-ippo57167'
@amazon_id = @diary.config['BOOKSTORE_AMAZON_ID'].to_s #'ipposjunkbox-22'
@rakuten_id = @diary.config['BOOKSTORE_RAKUTEN_ID'].to_s #'0005da7d.02b79257'
@reviewer_code = @diary.config['REVIEWER_CODE'].to_s
@reviewlink_url = @diary.config['REVIEWLINK_URL']
@flag_reviewlinklink = @diary.config['REVIEWLINK_LINK'] #true
@flag_net = @diary.config['nonet'] ? false : true
@expire = @diary.config['CACHE_EXPIRE']
@flag_cacheserver = @diary.config['CACHE_SERVER'] #true
@cache_base_dir = @diary.config['CACHE_DIRECTORY'].to_s
@user_lib_dir = @diary.config['USER_LIB_DIRECTORY'].to_s
ENV['http_proxy'] = @diary.config['PROXY'] if ENV['http_proxy'].nil? && defined?(@diary.config['PROXY'])
@flag_imagefiles = @diary.config['BOOKSTORE_IMAGEFILE']
@imagefiles = {} if @imagefiles.nil? && @flag_imagefiles
@flag_bk1_image = @diary.config['BOOKSTORE_BK1_IMAGE']
@url_bk1_image = @diary.config['BOOKSTORE_BK1_IMAGEURL']
@flag_bk1_xml = @diary.config['BOOKSTORE_BK1_XML']
else
@bk1_id, @amazon_id, @rakuten_id = '', '', ''
end
@flag_rl_refer = true if @flag_rl_refer.nil?
@shop_list = 'amazon bk1 yahoo asahiya jbook kinokuniya rakuten skysoft reviewlink' if @shop_list.empty?
@shop_list0 = 'amazon amazon.com skysoft a1books powells kinokuniya maruzen' if @shop_list0.empty?
@shop_list1 = 'amazon_uk bookshop' if @shop_list1.empty?
@expire = 12 if @expire.nil?
@cache_base_dir = @diary.logDirectory.chomp('/') + '/bookcache' if @cache_base_dir.to_s == ''
@cache_base_dir.chomp!('/')
@user_lib_dir = '../user/lib' if @user_lib_dir.to_s == ''
@user_lib_dir.chomp!('/')
#-----各位の環境に合わせて適時改変-----ココカラ-----
require "#{@user_lib_dir}/cookie" #必須・webagent用
require "#{@user_lib_dir}/webagent" #必須・webagent用
require "#{@user_lib_dir}/cache" #必須・キャッシュ用
require "#{@user_lib_dir}/cachebib" #必須・キャッシュ用
require "#{@user_lib_dir}/amazon" #以下は各書店用・不要な書店分は削除可
require "#{@user_lib_dir}/bk1"
require "#{@user_lib_dir}/yahoo" #eS! Booksとの提携
require "#{@user_lib_dir}/asahiya"
require "#{@user_lib_dir}/jbook"
require "#{@user_lib_dir}/kinokuniya"
require "#{@user_lib_dir}/rakuten"
require "#{@user_lib_dir}/skysoft"
require "#{@user_lib_dir}/esbooks"
# require "#{@user_lib_dir}/webcatplus"
require "#{@user_lib_dir}/cache_ippo" if @flag_cacheserver
#贋書店(cache-server)への接続
require "#{@user_lib_dir}/cachebib_simple"
#未設定書店はbookstoreに準じさせる
#blogmap, reviewlinkはこの中に入れてる
@cache_dir = {} #-----書誌情報の保存フォルダの指定-----
#無指定で"#{@cache_base_dir}/#{book.shop_id}"
# @cache_dir['amazon'] = "#{@cache_base_dir}/amz"
# @cache_dir['bk1'] = "#{@cache_base_dir}/bk1"
# @cache_dir['yahoo'] = "#{@cache_base_dir}/yho"
# @cache_dir['asahiya'] = "#{@cache_base_dir}/ash"
# @cache_dir['jbook'] = "#{@cache_base_dir}/jbk"
# @cache_dir['kinokuniya'] = "#{@cache_base_dir}/kin"
# @cache_dir['rakuten'] = "#{@cache_base_dir}/rak"
# @cache_dir['skysoft'] = "#{@cache_base_dir}/sky"
# @cache_dir['amazon_com'] = "#{@cache_base_dir}/amc"
# @cache_dir['a1books'] = "#{@cache_base_dir}/a1b"
# @cache_dir['powells'] = "#{@cache_base_dir}/pwl"
# @cache_dir['maruzen'] = "#{@cache_base_dir}/mrz"
# @cache_dir['amazon_uk'] = "#{@cache_base_dir}/amu"
# @cache_dir['bookshop'] = "#{@cache_base_dir}/bsp"
# @cache_dir['esbooks'] = "#{@cache_base_dir}/esb"
# @cache_dir['boople'] = "#{@cache_base_dir}/bpl"
# @cache_dir['webcatplus'] = "#{@cache_base_dir}/wcp"
# @cache_dir['rcom'] = "#{@cache_base_dir}/rcm"
#-----各位の環境に合わせて適時改変-----ココマデ-----
end
cachebibs = [] #-----全書店分cachebibの作成-----
bookstore_list.each{ |shop|
book = nil
# case shop #呼称がshop_nameに忠実でない場合はここで変更
# when 'amz', 'amazon', 'Amazon'; shop = 'amazon'
# end
defined = "defined?(CacheBib_#{shop})" #書店毎クラス宣言
cachebib = "CacheBib_#{shop}.new()"
unless eval(defined)
$stderr.puts "WAR; unknown-shop; code:#{shop}"
else
book = eval(cachebib)
case shop #-----書店毎カスタム部分-----
when 'amz', 'amazon'
book.affiliate_code = @amazon_id unless @amazon_id.empty?
when 'bk1'
book.affiliate_code = @bk1_id unless @bk1_id.empty?
book.flag_review = false #ここを入れないと重くなる(書評読)
unless @flag_bk1_image.nil?
book.flag_image = true
book.dir_image = @flag_bk1_image
book.url_image = @url_bk1_image unless @url_bk1_image.nil?
end
book.extend CacheBib_bk1_xml if @flag_bk1_xml
when 'rak', 'rakuten'
book.affiliate_code = @rakuten_id unless @rakuten_id.empty?
when 'rl', 'reviewlink'
book.flag_refer = @flag_rl_refer
book.affiliate_code = @reviewer_code unless @reviewer_code.empty?
book.url_head = @reviewlink_url unless @reviewlink_url.nil?
book.url = "#{@diary.date2monthlyfilelink(@diary.date, true)}#{anchor_link}"
end #-----書店毎カスタム部分・終り-----
book.expire = @expire
book.flag_net = @flag_net
unless @cache_dir[shop].nil?
book.cache_dir = @cache_dir[shop]
else
book.cache_dir = "#{@cache_base_dir.chomp('/')}/#{book.shop_id}/"
end
end
cachebibs << book
}
return cachebibs
end
def bookstore_x(str, type)
unless @flag_initial_bookstore_x #-----initialize-----
@flag_initial_bookstore_x = true
if @diary.respond_to?('config') then
@shop_list = @diary.config['BOOKSTORE_SHOP_LIST'].to_s
@shop_list0 = @diary.config['BOOKSTORE_SHOP_LIST_0'].to_s
@shop_list1 = @diary.config['BOOKSTORE_SHOP_LIST_1'].to_s
@no_image_file = @diary.config['NO_IMAGE_FILE'].to_s
@user_lib_dir = @diary.config['USER_LIB_DIRECTORY'].to_s
ENV['http_proxy'] = @diary.config['PROXY'] if ENV['http_proxy'].nil? && defined?(@diary.config['PROXY'])
@flag_imagefiles = @diary.config['BOOKSTORE_IMAGEFILE']
@imagefiles = {} if @imagefiles.nil? && @flag_imagefiles
end
@shop_list = 'amazon bk1 yahoo asahiya jbook kinokuniya rakuten skysoft reviewlink' if @shop_list.empty?
@shop_list0 = 'amazon amazon.com skysoft a1books powells kinokuniya maruzen' if @shop_list0.empty?
@shop_list1 = 'amazon_uk bookshop' if @shop_list1.empty?
@no_image_file = nil if @no_image_file.empty?
@user_lib_dir = '../user/lib' if @user_lib_dir.to_s == ''
@user_lib_dir.chomp!('/')
#-----各位の環境に合わせて適時改変-----ココカラ-----
require "#{@user_lib_dir}/cache" #必須・ISBNチェック用
require "#{@user_lib_dir}/cachebib" #必須・ISBNチェック用
#-----各位の環境に合わせて適時改変-----ココマデ-----
@bookstore_name = {} #-----提示する書店文字列の指定-----
#無指定でそのまま
# @bookstore_name['amazon'] = 'amazon'
# @bookstore_name['bk1'] = 'bk1'
@bookstore_name['yahoo'] = 'Yahoo!'
@bookstore_name['asahiya'] = '旭屋'
@bookstore_name['jbook'] = 'Jbook'
@bookstore_name['kinokuniya'] = '紀伊國屋'
@bookstore_name['rakuten'] = '楽天'
# @bookstore_name['skysoft'] = 'skysoft'
@bookstore_name['amazon_com'] = 'amazon.com'
@bookstore_name['a1books'] = 'A1Books'
@bookstore_name['powells'] = 'Powells.com'
@bookstore_name['maruzen'] = '丸善'
@bookstore_name['amazon_uk'] = 'amazon.co.uk'
@bookstore_name['bookshop'] = 'The Internet Bookshop'
@bookstore_name['esbooks'] = 'eS!'
# @bookstore_name['boople'] = 'boople'
# @bookstore_name['webcatplus'] = 'webcatplus'
@bookstore_name['rcom'] = '読共'
@bookstore_name['blogmap'] = 'bm'
@bookstore_name['reviewlink'] = 'rl'
end
case type
when :P, :UL, :DL
str.gsub!(BOOKSTOREX){ #ISBN検索
isbn1 = $1 #-----ISBN確認-----
newisbn = CacheBib.new.isbn_check(isbn1)
if newisbn != isbn1
mes_str << "Warrning; ISBN-error; #{isbn1} -> #{newisbn}\n"
$stderr.puts "WAR; ISBN-error; #{isbn1} -> #{newisbn}"
end
isbn1 = newisbn
isbn2 = isbn1.delete('-')
@bookstore_list = @shop_list.split(/\s+/)
@bookstore_list = @shop_list0.split(/\s+/) if isbn2 =~ /^0/
@bookstore_list = @shop_list1.split(/\s+/) if isbn2 =~ /^1/
#-----全書店分cachebibの作成-----
cachebibs = cachebibs_make(@bookstore_list)
#-----書店にネット接続/キャッシュ読-----
if @flag_cacheserver #-----cache鯖先読-----
cachebibs_sum = CacheBib_ippo_sum.new
cachebibs_sum.flag_net = @flag_net
cachebibs_sum.gets(cachebibs, isbn1)
end
infolist = [] #-----通常のキャッシュ読-----
@bookstore_list.each{ |bookstore| infolist << nil } #書店情報リスト
threads = [] #thread化
@bookstore_list.each_index{ |i|
bookstore = @bookstore_list[i]
thr = Thread.start(i){ |j| #thread化
# j = i #threadでない場合、この行を戻して「thread化」行を落とす。
#threadでは順番が先着順でstderr表示等が乱れるかもしれない。
book = cachebibs[j]
info = book.get_data(isbn1)
info['shop_id'] = book.shop_id
info["url_bibinfo"] = book.url_bibinfo
info["url_isbnsearch"] = defined?(book.url_isbnsearch) ? book.url_isbnsearch : info["url_bibinfo"]
info["bookstore_name"] = @bookstore_name[bookstore] || bookstore
info["bookstore_code"] = bookstore
#あるいはbook.shop_idだが、設定ファイルと同文字列の方がやりやすいか
begin #-----word delivery-----
info['word_delivery'] = book.word_delivery
rescue Exception #-----for no-define-word_delivery = rcom-----
$stderr.puts "WAR; delivery-decode-error; #{isbn1} - #{bookstore}"
info['word_delivery'] = [nil, nil]
end
infolist[j] = info
} #thread化
threads << thr #thread化
} #幾つか必要そうで標準添付でないwordをinfoに加えている
threads.each{ |thr| thr.join } #thread化
bookstore_x_string(isbn1, infolist) #-----表示文字列作成-----
}
str.gsub!(BOOKSTORE_KEYWORD_SEARCH){ #キーワード検索
keyword = $1
line = []
bookstore_list = @shop_list.split(/\s+/)
cachebibs = cachebibs_make(bookstore_list)
bookstore_list.each_index{ |i|
bookstore, book = bookstore_list[i], cachebibs[i]
begin
key_str = book.url_search(1, keyword)
shop_str = @bookstore_name[bookstore] || bookstore
line << %Q|#{shop_str}|
rescue NameError #url_searchが無い場合は跳ばす
end
}
if line.size > 0
line = %Q|【 #{keyword} : #{line.join(' / ')} 】| #表示文字列
else
line = ''
end
line
}
str.gsub!(BK1_ID){ #BK1-bibid用
"(SHOP:bk1,#{$1})"
}
str.gsub!(STORE){ #各書店用
bookstore, id = $1.strip, $2.strip
bookstore_list = [bookstore]
cachebibs = cachebibs_make(bookstore_list)
bookstore, book = bookstore_list.first, cachebibs.first
book.get_data_from_id(id)
info = book.info
info['shop_id'] = book.shop_id
info['url_bibinfo'] = book.url_bibinfo
info["url_isbnsearch"] = defined?(book.url_isbnsearch) ? book.url_isbnsearch : info["url_bibinfo"]
info['word_delivery'] = book.word_delivery
info['bookstore_name'] = @bookstore_name[bookstore] || bookstore
info['bookstore_code'] = bookstore
bookstore_x_string(id, [info]) #-----表示文字列作成-----
}
when :AFTER_P, :AFTER_UL, :AFTER_DL
str.gsub!(%r|
' return mes_str end def anchor_link anchor = '' if @diary.paragraphAnchor if @diary.anchorEachTopic anchor = "_t#{@diary.instance_eval{@cntTopic}}_#{@diary.instance_eval{@cntParagraph + 1}}" else anchor = "_#{@diary.instance_eval{@cntParagraph + 1}}" end end return anchor end def imagefile_write ( yearmonth = nil ) #-----画像リスト用----- yearmonth = @diary.date[0..5] if yearmonth.nil? imagefile = @diary.logDirectory + yearmonth + '.image' open(imagefile).each{ |line| # date, anchor, file, width, height, isbn = line.chomp.split("\t") data = line.chomp.split("\t") date = data.shift @imagefiles[date] = [] if @imagefiles[date].nil? @imagefiles[date] << data unless @imagefiles[date].include?(data) } if File.exist?(imagefile) open(imagefile, 'w'){ |fp| @imagefiles.keys.sort.each{ |date| @imagefiles[date].each{ |info| fp.puts "#{date}\t#{info.to_a.join("\t")}" } if date =~ /^#{yearmonth}/ } } end end