# $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 #ISBN4(?),0 bk1 bk1 #ISBN4 yahoo Yahoo! Books #ISBN4 asahiya 旭屋書店 #ISBN4 jbook Jbook #ISBN4 kinokuniya 紀伊國屋書店 #ISBN4,0(!) rakuten 楽天ブックス #ISBN4 skysoft skysoft #ISBN4,0(!) amazon.com amazon.com #ISBN0 a1books a1books #ISBN0 powells powells.com #ISBN0 maruzen 丸善 #ISBN0 amazon.co.uk amazon.co.uk #ISBN1 bookshop The Internet Bookshop #ISBN1 esbooks eS!BOOKS #? boople boople #未 webcatplus webcatplus #? rcom 読書共同体(否書店) #未 rl 書評リンク(否書店) #試 アソシエイト・プログラムに参加している場合は ndiary.conf に以下の行を追加 もちろん自分の ID に直して BOOKSTORE_BK1_ID = 'p-not00114' # bk1 BOOKSTORE_AMAZON_ID = 'notsfragmen-22' # amazon.co.jp BOOKSTORE_RAKUTEN_ID = '0001fc8b.1fe901a6' # 楽天 キャッシュの更新時間間隔とキャッシュファイルのフォルダ位置 CACHE_EXPIRE = 12 CACHE_DIRECTORY = '../log/bookcache/' (注:Amazonであれば../log/bookcache/amz/となります(初期設定)) (注:それらのフォルダは手動で作成しておいて下さい) プロクシの設定(user/lib/webagent.rbの機能) PROXY = 'http://proxy.hoge.com:8080' bk1の画像利用(ダウンロード)指定(画像格納フォルダ) BOOKSTORE_BK1_IMAGE = '../www/' #ダウンロード位置 BOOKSTORE_BK1_IMAGEURL = './' #リンク位置(htmlにはこちらが記述される) 画像が無い場合に代替表示する画像の指定(source(img-tag)で表記) NO_IMAGE_FILE = 'no image' 書評リンク(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|

\s*

|, '') #余計なpの除去(p内div対策の一環) when :HTML if @diary.kind_of?(PastDiary) && @flag_imagefiles imagefile_write(@diary.date[0..5]) end end end def bookstore_x_string( code, infolist ) #-----表示文字列作成----- #@flag_imagefiles, @imagefiles, @no_image_file isbn = nil if code.to_s.delete('-') =~ /^[\dx]{10}$/i isbn, code = code, 'ISBN' + code else code = "BOOK:#{infolist.first['shop_id']}:#{code}" unless code.nil? end mes_str = '

' img_str = '' #-----書影情報作成----- storelist = [] #-----各書店情報リスト作成----- flag_image = nil infolist.each{ |info| #書影書店決定 bookstore = info['bookstore_code'] flag_image = bookstore if !info['image'].nil? && (bookstore == 'amazon') && flag_image.nil? flag_image = bookstore if !info['image_local'].nil? && (bookstore == 'bk1') flag_image = bookstore if !info['image'].nil? && (bookstore == 'rakuten') && flag_image.nil? } #image_store = 'bk1' #とかすると書影店を固定できる infolist.each{ |info| next if info.nil? bookstore = info['bookstore_code'] new_str = '' if flag_image == bookstore #書影確認 img_src = info['image'] img_src = info['image_local'] if bookstore == 'bk1' height = info['image_height'].to_i != 0 ? info['image_height'].to_s : '140' width = info['image_width'].to_i != 0 ? info['image_width'].to_s : '100' img_str << %Q!#{bookstore} ! #画像リスト作成・bookstore_x自身には不要 if @flag_imagefiles data = [anchor_link, img_src, info['image_width'].to_s, info['image_height'].to_s, code] @imagefiles[@diary.date] = [] if @imagefiles[@diary.date].nil? unless @imagefiles[@diary.date].include?(data) flag = true @imagefiles[@diary.date].each_index{ |j| a, i, iw, ih, is = @imagefiles[@diary.date][j] if a == anchor_link && is == code @imagefiles[@diary.date][j] = data flag = false break end } if flag @imagefiles[@diary.date] << data end end end #画像リスト作成ここまで new_str << ' ' elsif !info['image'].nil? new_str << ' 絵' end delivery, flag = info['word_delivery'] #配送期日確認 if flag new_str << ' '+ delivery + '' end if info['review_num'].to_i > 0 || info['reviews'].to_a.size > 0 #書評確認 rev_num = info['review_num'].to_s rev_num = info['reviews'].size.to_s if rev_num == '' new_str << ' ' + rev_num + "評" end if new_str.size > 0 #掠らなかった書店は無視 if flag #書店名確認 new_str = info['bookstore_name'] + new_str else new_str = '' + info['bookstore_name']+ '' + new_str end if flag == 'over' #rl用 new_str = '' + info['bookstore_name']+ '' end end storelist << new_str if new_str.size > 0 } if !@no_image_file.nil? #書影が無かった場合の書影情報 img_str = @no_image_file if img_str == '' end rl = CacheBib_reviewlink.new() rl.isbn = isbn rl.flag_refer = true rl.affiliate_code = @reviewer_code unless @reviewer_code.empty? rl.url_head = @reviewlink_url unless @reviewlink_url.nil? rl.url = "#{@diary.date2monthlyfilelink(@diary.date, true)}#{anchor_link}" rl_str = rl.tag infolist.delete(nil) #-----書誌情報作成----- info = CacheBib.new.merge_info(infolist) #あるだけまとめてしまって作成 info["isbn"] = isbn mes_str << img_str #書影情報埋込 mes_str << rl_str #書評リンク情報をこっそり埋込 mes_str << "【 " + storelist.join(" / ") + " 】\n" if storelist.size > 0 #各書店情報リスト埋込 # mes_str << blogmap_trackback(isbn) mes_str << "題:" + info['title'] + "\n" if !info['title'].nil? mes_str << "続:" + info['series'] + "\n" if !info['series'].nil? mes_str << "著:" + info['author'] + "\n" if !info['author'].nil? mes_str << "訳:" + info['translator'] + "\n" if !info['translator'].nil? mes_str << "符:ISBN" + info['isbn'] + "\n" if !info['isbn'].nil? mes_str << "標:" + info['label'] + "\n" if !info['label'].nil? mes_str << "刊:" + info['publisher'] + "\n" if !info['publisher'].nil? mes_str << "年:" + info['pubdate'] + "\n" if !info['pubdate'].nil? mes_str << "型:" + info['pubsize'] + "\n" if !info['pubsize'].nil? mes_str << "頁:" + info['page'] + "\n" if !info['page'].nil? mes_str << "値:" + info['price'] + "\n" if !info['price'].nil? mes_str << "文:" + info['desc'] + "\n" if !info['desc'].nil? mes_str = mes_str.strip + '
' #書誌情報埋込 mes_str << '

' 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